cevap

4

Bellek izi konusunda endişeleriniz varsa, bu alanı tamamlayıcı nesneye taşıyabilirsiniz.

Evet, Foo sınıfının her örneği pi değerine sahip olacaktır - Scala derleyicisi bu bildirimi ortadan kaldırmaz. JVM yansıması, sınıf üyeleri üzerindeki son değiştiricileri kaldırmanıza olanak tanır ve Unsafe nesnesi, bunların değiştirilmesine bile izin verir. Yani - Scala derleyicisi bu alanı kaldırarak şaşırtıcı sonuçlara sahip kod üretebilir, bu nedenle bu optimizasyon uygulanmaz. Scala kodunda final hissettiren bir şey baytkodu düzeyde final olmayabilir bu yüzden

... 
    minor version: 0 
    major version: 50 
    flags: ACC_PUBLIC, ACC_SUPER 
... 
{ 
    private final int pi; 
    flags: ACC_PRIVATE, ACC_FINAL 


    public final int pi(); 
    flags: ACC_PUBLIC, ACC_FINAL 
    LineNumberTable: 
     line 243: 0 
    LocalVariableTable: 
     Start Length Slot Name Signature 
... 

Aslında, bazı derleyici dönüşümler (örneğin uzmanlık) bile, altında-luk üyeleri üzerinde son değiştiriciler da kaldırabilir.

Bu

:

class Foo[@specialized T] { 
    final val pi: T = null.asInstanceOf[T] 
} 

olur: Yukarıdaki

... 
    public final T pi; 
    flags: ACC_PUBLIC, ACC_FINAL 
    Signature: #9       // TT; 


    public T pi(); 
    flags: ACC_PUBLIC 
    LineNumberTable: 
     line 243: 0 
    ... 

, pi erişimci yöntemi (diğer bir deyişle, gaz giderici) artık kesindir.

Ayrıca, JVM'deki JIT, bu üyeyi çalışma zamanında bellekte nesne temsilinden kaldırmaz - 32 bit JVM'deki Foo nesnesinin çalışma zamanı boyutu, 16 bayt (8 baytlık nesne başlığı + 4 bayt) olur 8 baytlık bir sınırda yuvarlanmış bir tamsayı alanı için). Bununla birlikte, JIT, son alandaki sabit değeri kodun bazı bölümlerine çevirmeye karar verebilir, böylece bazı alan yazıları ortadan kaldırılır.

3

Her örneğin alanı pi olacak, aynı zamanda sıfır değerine sahip olacaktır.

pi sabit bir değer tanımlamasıdır. "Erişimci" sadece sabitini döndürür.

Bu, yeterince sıkı çalıştığınızda, ayrı derleme ve satır içi koşullar altında sorunlara neden olabilir.

{ 
    private final int pi; 
    flags: ACC_PRIVATE, ACC_FINAL 

    public final int pi(); 
    flags: ACC_PUBLIC, ACC_FINAL 
    Code: 
     stack=1, locals=1, args_size=1 
     0: iconst_3  
     1: ireturn  
     LocalVariableTable: 
     Start Length Slot Name Signature 
       0  2  0 this LFoo; 
     LineNumberTable: 
     line 8: 0 

    public Foo(); 
    flags: ACC_PUBLIC 
    Code: 
     stack=1, locals=1, args_size=1 
     0: aload_0  
     1: invokespecial #14     // Method java/lang/Object."<init>":()V 
     4: return   
     LocalVariableTable: 
     Start Length Slot Name Signature 
       0  5  0 this LFoo; 
     LineNumberTable: 
     line 13: 0 
} 

Sadece yansıması üzerine, kendimi ikna etmeye:

scala> res5.tail 
res16: Iterable[reflect.runtime.universe.Symbol] = List(value pi) 

scala> res5.last.asTerm.isAccessor 
res18: Boolean = false 

scala> res5.head.asTerm.isAccessor 
res19: Boolean = true 

scala> res0 reflectField res5.last.asTerm 
res21: reflect.runtime.universe.FieldMirror = field mirror for Foo.pi (bound to [email protected]) 

scala> res21.get 
res22: Any = 0 
İlgili konular