2008-10-09 9 views
6

J'essaye d'attraper une ClassCastException en désérialisant un objet de xml.Comment attraper ClassCastException?

Ainsi,

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. 
} 

Et pourtant, ce ne sera pas comme l'exception ne soit pas pris. Que suggérerais-tu?

+0

Retagged à utiliser exceptions releated plus courantes balises. –

Répondre

8

Le code dans la question devrait vous donner un avertissement de cast non contrôlé. Écoutez -Xlint.

Tout le compilateur sait que T est ses limites, ce qu'il n'a probablement pas (autre que l'extension explicite d'Object et un super du type nul). Donc, effectivement, la distribution à l'exécution est (Objet) - pas très utile.

Ce que vous pouvez faire est de passer une instance de la classe du type paramétré (en supposant qu'elle ne soit pas générique).

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) { 
      ... 
     } 
    } 
} 

Ou comme méthode générique:

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

Eh bien, je ne peux pas utiliser instanceof opérateur comme la méthode est un paramétrisé:

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

et génériques en Java sont à la compilation seulement.

+0

Cela ne suggère-t-il pas que la distribution à T est réellement faite par l'appelant, pas par la méthode elle-même? –

+0

Je ne suis pas certain d'avoir compris votre point. Comme un hack rapide, je retourne un objet à partir de restore (..) et je fais une instanceof check à un niveau supérieur, pas de génériques impliqués (car ils n'aident pas de toute façon). Pourtant, c'est moche. – yanchenko

3

Il n'y aura pas de ClassCastException, sauf si votre T a une certaine 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; 
    } 
} 

Dans l'exemple ci-dessus, il y aura aucune exception ClassCastException dans les 5 premiers appels à cast et castBaseNumber. Seul le 6ème appel lève une exception ClassCastException, car le compilateur convertit efficacement cast() en retour (Object) o et castBaseNumber() en renvoie (Number) o ;. Wenn vous écrivez

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

Vous obtiendrez un ClassCastException, mais pas whithin la méthode de distribution, mais l'affectation à l'art.

Par conséquent, je pense que votre "T" n'est pas seulement "T", mais "T extends Something". Donc, vous pouvez vérifier:

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

Mais cela conduira encore à une erreur plus tard, lorsque vous utilisez votre classe.

public Reader<T extends Number>{...} 

Long l = new Reader<Long>("file.xml").getValue(); // there might be the ClassCastException 

Dans ce cas, seuls les conseils de Tom peuvent vous aider.

0

Si vous ne pouvez pas utiliser instaceof vous pourriez être en mesure d'utiliser la méthode de IsAssignableFrom de classe

Questions connexes