2015-05-10 17 views
6

Bu basit sınıfın bayt kodunu incelediğimizde, derleyicinin yerel bir değişkenle ilgili herhangi bir bilgiyi final olmak üzere tutmadığı sonucuna vardım. Bu garip görünüyor, çünkü HotSpot derleyicisinin bu bilgiyi optimizasyon için kullanabileceğine inanıyorum.Değişken 'final' değiştiricisi Bytecode'da kayboldu mu?

Kod:

public static void main(String[] args) 
{ 
    final int i = 10; 
    System.out.println(i); 
} 

Bytecode:

public static void main(java.lang.String[]); 
descriptor: ([Ljava/lang/String;)V 
flags: ACC_PUBLIC, ACC_STATIC 
Code: 
    stack=2, locals=2, args_size=1 
    0: bipush  10 
    2: istore_1  
    3: getstatic  #16     // Field java/lang/System.out:Ljava/io/PrintStream; 
    6: bipush  10 
    8: invokevirtual #22     // Method java/io/PrintStream.println:(I)V 
    11: return   
    LineNumberTable: 
    line 7: 0 
    line 8: 3 
    line 9: 11 
    LocalVariableTable: 
    Start Length Slot Name Signature 
     0  12  0 args [Ljava/lang/String; 
     3  9  1  i I 

dışında bir yerel değişkenin erişim bayraklarını korumak için herhangi bir özel nedeni değil var mı disk alanı tasarrufu? Çünkü bana göre, final olmanın bir değişkenin nispeten önemsiz bir özelliği olduğu anlaşılıyor.

+4

sıcak nokta JITs dahili SSA'sı temsiline bayt kodu dönüşümü AIUI yine finalness gereksiz hale getirir, aşağıdaki gibi bir şey farklılık gösterebilir. Ve java-topraklarında baytkod seviyesinde gerçek olmayan başka kurgular vardır, örn. generics – the8472

+0

Jenerikler için mantıklıdır, çünkü aşağı doğru uyumluluğu bozarlardı, ama “final” en başından beri oradaydı. – Clashsoft

+0

kontrol özel durumlar başka bir örnek olurdu. – the8472

cevap

7

final değiştiricisi baytkodunda bulunmaz, ancak derleyici bu bilgiyi zaten en iyi duruma getirmek için kullanır. Örneğiniz bunu göstermese de, derleyici, yöntemin bytecode temsilinde final değişkeninin değerini artırabilir ve bu da daha iyi bir performans sağlar.

public int addFinal() { 
    final int i = 10; 
    final int j = 10; 
    return i + j; 
} 

public int addNonFinal() { 
    int i = 10; 
    int j = 10; 
    return i + j; 
} 

üretilen bayt kodu her yöntem için sırasıyla:

// addFinal 
bipush 10 
istore_1 
bipush 10 
istore_2 
bipush 20 
ireturn 


// addNonFinal 
bipush 10 
istore_1 
bipush 10 
istore_2 
iload_1 
iload_2 
iadd 
ireturn 
İlgili konular