2017-07-26 4 views
1

Compte tenu d'un simple try-catch-finally méthode:Que manque-t-il dans LocalVariableTable?

public void t() { 
    try { 
     f1(); 
    }catch(Exception e) { 
     f2(); 
    }finally { 
     f3(); 
    } 
} 

Avec "javac -g", il est compilé:

public void t(); 
    descriptor:()V 
    flags: ACC_PUBLIC 
    Code: 
stack=1, locals=3, args_size=1 
    0: aload_0 
    1: invokespecial #15     // Method f1:()V 
    4: goto   26 
    7: astore_1 
    8: aload_0 
    9: invokespecial #18     // Method f2:()V 
    12: aload_0 
    13: invokespecial #21     // Method f3:()V 
    16: goto   30 
    19: astore_2 
    20: aload_0 
    21: invokespecial #21     // Method f3:()V 
    24: aload_2 
    25: athrow 
    26: aload_0 
    27: invokespecial #21     // Method f3:()V 
    30: return 
Exception table: 
    from to target type 
     0  4  7 Class java/lang/Exception 
     0 12 19 any 
LineNumberTable: 
    line 7: 0 
    line 8: 4 
    line 9: 8 
    line 11: 12 
    line 10: 19 
    line 11: 20 
    line 12: 24 
    line 11: 26 
    line 13: 30 
LocalVariableTable: 
    Start Length Slot Name Signature 
     0  31  0 this Lsample/Sample; 
     8  4  1  e Ljava/lang/Exception; 
StackMapTable: number_of_entries = 4 
    frame_type = 71 /* same_locals_1_stack_item */ 
    stack = [ class java/lang/Exception ] 
    frame_type = 75 /* same_locals_1_stack_item */ 
    stack = [ class java/lang/Throwable ] 
    frame_type = 6 /* same */ 
    frame_type = 3 /* same */ 

Notez les habitants = 3, mais il n'y a que deux articles en le LocalVariableTable. La ligne de bytecode 19 (astore_2) et 24 (aload_2) indiquent que la troisième variable locale existe.

La question est: quelle est la troisième variable locale et pourquoi est-elle omise dans LocalVariableTable?

Répondre

1

La troisième variable locale est un détail d'implémentation du bloc finally. Dans le cas où votre try/catch lève une variable, il doit stocker temporairement l'exception pour pouvoir appeler f3() avant de la relancer, et c'est ce que fait le slot 2.

+0

Design intéressant. Cela fonctionnerait-il aussi, si la variable est simplement laissée sur la pile d'opérandes avant que 'f3()' soit appelé? (Cela pourrait augmenter la profondeur maximale de la pile?) – dejvuth

+0

Dans ce cas, la troisième variable locale devrait-elle être de type Throwable? Mais pourquoi n'apparaît-il pas dans LocalVariableTable? – ziyi

+0

Dans ce cas, il aurait pu être laissé sur la pile d'opérandes, mais le codegen de Javac essaie d'éviter cela autant que possible pour diverses raisons. Si je devais deviner pourquoi il n'apparaît pas dans le tableau, c'est parce qu'il ne correspond à aucune variable de niveau source. Le LocalVariableTable est juste pour le débogage. – Antimony