2009-11-25 4 views
2

Supposons que InvalidResourceException est une sous-classe de ResourceException. Définissez deux méthodes:Les blocs catch Java utilisent une liaison statique?

void handleException(ResourceException e) { 
    System.out.println("ResourceException " + e.toString()); 
} 
void handleException(InvalidResourceException e) { 
    System.out.println("InvalidResourceException " + e.toString()); 
} 

maintenant le code suivant:

imprime ceci:

ResourceException: com.myPackage.InvalidResourceException: invalid resource 

Mais le code suivant:

try { 
    throw new InvalidResourceException("invalid resource"); 
    } catch (InvalidResourceException e) { 
    handleException(e); 
    } catch (ResourceException e) { 
    handleException(e); 
    } 

imprime ceci:

InvalidResourceException: com.myPackage.InvalidResourceException: invalid resource 

Ceci est avec le JDK de Sun 1.5.0_15.

Est-ce compatible avec le standard Java?

Que devrait faire ce code?

Exception e = new InvalidResourceException("invalid resource"); 
handleException(e); 

Que devrait faire ce code?

Exception e = new InvalidResourceException("invalid resource"); 
if (e instanceOf ResourceException) { 
    handleException(e); 
} else if (e instanceOf InvalidResourceException) { 
    handleException(e); 
} else { 
    handleException(e): 
} 
+0

Ce comportement me semble utile. –

Répondre

11

Oui. C'est correct. Les surcharges sont toujours résolues statiquement.

Aucun de vos 2 derniers exemples ne sera compilé car le type statique de e est Exception, et aucune de vos surcharges n'accepte ce type.

Edit:

Notez que votre dernier exemple est pas vraiment un analogue direct au bloc try/catch. Dans le try/catch, vous avez deux variables appelées e: une pour chaque capture, et leurs types statiques sont respectivement InvalidResourceException et ResourceException. Dans votre dernier exemple, vous avez une seule variable nommée e, et son type statique est Exception. Si vous avez ajouté de nouvelles variables et que vous les avez assignées avec un cast, vous obtiendrez le même comportement que votre try/catch (bien que vous deviez perdre la dernière branche else).

+0

Résoudre des surcharges est un peu plus compliqué que d'être simplement "statique" - il y a aussi un aspect dynamique. Voir pour les détails. –

+0

Il y a un aspect dynamique à * l'invocation de méthode * (la section de la JLS à laquelle vous êtes lié), mais * la résolution de surcharge * est une opération strictement statique (ie: à la compilation). En fait, la partie de la JLS que vous avez liée pour sauvegarder ceci: la seule partie qui mentionne les surcharges (autre que la vue d'ensemble au début) est §15.12.2, «Étape de compilation 2: Déterminer la signature de la méthode». –

1

En ce qui concerne la première partie de votre question, la méthode correcte à appeler est déterminée au moment de la compilation en fonction du type déclaré comme variable. Par exemple. Si vous avez modifié l'instruction catch pour intercepter InvalidResourceException, la surcharge handleException (InvalidResourceException) sera appelée à la place. En ce qui concerne la deuxième partie de votre question, la JVM trouve simplement la première instruction catch capable de gérer l'exception levée. Si vous deviez lancer une exception ResourceException à la place, le second bloc catch serait exécuté.

La troisième partie ne compilera pas, car aucune méthode handleException() appropriée n'existe pour gérer une exception simple.

La dernière partie échouera également à compiler pour la même raison que la troisième partie.

0

Vous attendez quelque chose appelé "double dispatch" qui n'est pas supporté par java.

Questions connexes