2010-07-24 36 views
4

J'ai le scénario suivant:Comment puis-je faire baissés en toute sécurité et éviter un ClassCastException

public class A { 
} 

public class B extends A { 
} 

public class C extends B { 
    public void Foo(); 
} 

J'ai une méthode qui peut renvoyer la classe A, B ou C et je veux lancer en sécurité vers C, mais seulement si le type de classe est C. C'est parce que j'ai besoin d'appeler Foo() mais je ne veux pas l'exception ClassCastException.

+5

Avant d'aller à plein régime en utilisant 'instanceof', jetez un oeil à des postes comme celui-ci, comme en utilisant' instanceof' est souvent un signe de un défaut de conception: http://stackoverflow.com/questions/2750714/is-instanceof-considered-bad-practice-if-so-under-what-circumstances-is-instanc et http://stackoverflow.com/questions/ 2790144/avoid-instanceof-in-java – Abel

+0

Envisagez d'utiliser et d'interface, de cette façon vous vous débarrasserez de toutes les nuances et restrictions qui vous sont imposées par le modèle d'héritage unique de Java. interface publique IFoo {public void foo();} –

Répondre

6

Pouvez-vous le faire?

if (obj instanceof C) { 
    ((C)obj).Foo(); 
} 
else { 
    // Recover somehow... 
} 

Cependant, s'il vous plaît voir les autres commentaires dans cette question, comme une utilisation excessive de instanceof est parfois (pas toujours) un signe que vous devez repenser votre conception.

+0

Merci, je vais envisager de changer mon design. C'est juste qu'il ajoute beaucoup de passe-partout pour toujours utiliser le type C. –

+0

instanceof est comme goto, si vous l'utilisez alors vous devez prendre le temps et refactoriser votre source :) – vach

2

Vous pouvez vérifier le type avant la coulée en utilisant instanceof

Object obj = getAB_Or_C(); 

if (obj instanceof C) { 
    C c = (C) obj; 
} 
2

Ce que vous devez faire est quelque chose comme ce qui suit, vous n'avez pas besoin de jeter.

public class A { 
    public void foo() { 
     // default behaviour. 
    } 
} 

public class B extends A { 
} 

public class C extends B { 
    public void foo() { 
     // implementation for C. 
    } 
} 
+0

Parfois, parfois non. Cela n'a pas toujours de sens pour A d'avoir une méthode foo(), et vous ne pourrez peut-être pas changer la classe A. –

+0

Je ne peux pas changer la classe A - cela fait partie du paquet GWT UI. –

+3

La prochaine fois ajoutez une telle information à votre question. –

2

Comme alternative à instanceof, envisager

interface Fooable { void foo(); } 

class A implements Fooable { ... }