Compte tenu de ce programme:
class Test {
public static void main(String[] args) {
try {
throw new NullPointerException();
} catch (NullPointerException npe) {
System.out.println("In catch");
} finally {
System.out.println("In finally");
}
}
}
Du soleil, javac
(v 1.6.0_24) produit la suite de bytecode:
public static void main(java.lang.String[]);
// Instantiate / throw NPE
0: new #2; // class NullPointerException
3: dup
4: invokespecial #3; // Method NullPointerException."<init>":()V
7: athrow
// Start of catch clause
8: astore_1
9: getstatic #4; // Field System.out
12: ldc #5; // "In catch"
14: invokevirtual #6; // Method PrintStream.println
17: getstatic #4; // Field System.out
// Inlined finally block
20: ldc #7; // String In finally
22: invokevirtual #6; // Method PrintStream.println
25: goto 39
// Finally block
// store "incomming" exception(?)
28: astore_2
29: getstatic #4; // Field System.out
32: ldc #7; // "In finally"
34: invokevirtual #6; // Method PrintStream.println
// rethrow "incomming" exception
37: aload_2
38: athrow
39: return
Avec l'exception suivante table:
Exception table:
from to target type
0 8 8 Class NullPointerException
0 17 28 any
28 29 28 any
Ma question est: Pourquoi sur la terre ne comprennent que la dernière entrée dans la table d'exception?!
Si je comprends bien, il dit en gros "si l' astore_2
lance une exception, l'attraper, et réessayer la même instruction".
Une telle entrée est produit, même avec vide try / catch / finally clauses telles que
try {} catch (NullPointerException npe) {} finally {}
Quelques observations
- Eclipse compilateur ne génère aucune exception de ce type d'entrée de la table
- La JVM spec ne documentent pas des exceptions d'exécution pour l'
astore
instruction. - Je sais que c'est légal pour la JVM de jeter
VirtualMachineError
pour les instructions. Je suppose que le propre entrée empêche toute erreur de la propagation de l'instruction.