How to catch a ClassCastException?

I am trying to catch a ClassCastException when deserializing an object from xml.

So,

try { restoredItem = (T) decoder.readObject(); } catch (ClassCastException e){ //don't need to crash at this point, //just let the user know that a wrong file has been passed. } 

And yet it will not be like an exception does not get. What would you suggest?

+6
java exception exception-handling
source share
4 answers

The code in the question should give you a warning without warning. Listen -Xlint.

All that the compiler knows about T is its boundaries, which it probably does not have (except for an explicit extension of Object and a super zero type). Thus, the effect at startup (Object) is not very useful.

What you can do is pass an instance of a class of a parameterized type (if it is not shared).

 class MyReader<T> { private final Class<T> clazz; MyReader(Class<T> clazz) { if (clazz == null) { throw new NullPointerException(); } this.clazz = clazz; } public T restore(String from) { ... try { restoredItem = clazz.cast(decoder.readObject()); ... return restoredItem; } catch (ClassCastException exc) { ... } } } 

Or as a general method:

  public <T> T restore(Class<T> clazz, String from) { ... try { restoredItem = clazz.cast(decoder.readObject()); ... 
+8
source share

There will be no ClassCastException exceptions when your T has some base:

 public class GenericsTest { public static void main(String[] args) { System.out.println(cast(Integer.valueOf(0))); System.out.println(GenericsTest.<Long> cast(Integer.valueOf(0))); System.out.println(GenericsTest.<Long> cast("Hallo")); System.out.println(castBaseNumber(Integer.valueOf(0))); System.out.println(GenericsTest.<Long> castBaseNumber(Integer.valueOf(0))); System.out.println(GenericsTest.<Long> castBaseNumber("Hallo")); } private static <T extends Number> T castBaseNumber(Object o) { T t = (T)o; return t; } private static <T> T cast(Object o) { T t = (T)o; return t; } } 

In the above example, there will be no ClassCastException in the first 5 calls to cast and castBaseNumber. Only the 6th call throws a ClassCastException, because the compiler efficiently translates cast () to return (Object) o; and castBaseNumber () to return (Number) o ;. Wenn you write

 String s = GenericsTest.<Long> cast("Hallo"); 

You will get a ClassCastException, but not in the cast-method, but when you assign s.

So I really think that your T is not just T, but T is expanding something. So you can check:

 Object o = decoder.readObject(); if (o instanceof Something) restoredItem = (T) o; else // Error handling 

But this will still result in an error later when you use your class.

 public Reader<T extends Number>{...} Long l = new Reader<Long>("file.xml").getValue(); // there might be the ClassCastException 

In this case, only Tom advise can help.

+3
source share

Well, I cannot use the instanceof operator, since the method is parameterized:

 public T restore(String from){ ... restoredItem = (T) decoder.readObject(); ... } 

And generics in Java is only compilation time.

0
source share

If you cannot use instaceof, you can use the isAssignableFrom method for the class

0
source share

All Articles