class Foo {
final val pi = 3
}
Her Foo
nesnesinin pi
üyesi var mı? Bu yüzden tamamlayıcı nesnesine pi
koymalı mıyım?Son vals, nesne boyutunu artırır mı?
class Foo {
final val pi = 3
}
Her Foo
nesnesinin pi
üyesi var mı? Bu yüzden tamamlayıcı nesnesine pi
koymalı mıyım?Son vals, nesne boyutunu artırır mı?
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.
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