Kiedyś tak myślałem private val
i tak private final val
jest, dopóki nie zobaczyłem sekcji 4.1 w Scala Reference:
Definicja wartości stałej ma postać
final val x = e
gdzie e jest wyrażeniem stałym (§ 6.24). Ostateczny modyfikator musi być obecny i nie można podawać adnotacji typu. Odniesienia do stałej wartości x same są traktowane jako wyrażenia stałe; w generowanym kodzie są zastępowane prawą stroną definicji e.
Napisałem test:
class PrivateVal {
private val privateVal = 0
def testPrivateVal = privateVal
private final val privateFinalVal = 1
def testPrivateFinalVal = privateFinalVal
}
javap -c
wynik:
Compiled from "PrivateVal.scala"
public class PrivateVal {
public int testPrivateVal();
Code:
0: aload_0
1: invokespecial #19 // Method privateVal:()I
4: ireturn
public int testPrivateFinalVal();
Code:
0: iconst_1
1: ireturn
public PrivateVal();
Code:
0: aload_0
1: invokespecial #24 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_0
6: putfield #14 // Field privateVal:I
9: return
}
Kod bajtowy jest taki, jak powiedział Scala Reference: private val
nie private final val
.
Dlaczego scalac nie traktuje po prostu private val
jako private final val
? Czy jest jakiś podstawowy powód?
private
modyfikator zakresu ma taką samą semantykę jak package private
w Javie. Możesz chcieć powiedzieć private[this]
.
private
chodzi mi o to, że jest to widoczne tylko dla instancji tej klasy, private[this]
tylko ta instancja - z wyjątkiem instancji tej samej klasy , private
nie pozwala nikomu (w tym z tego samego pakietu) na dostęp do wartości.
val
jest już niezmienne, dlaczego w ogóle potrzebujemyfinal
słowa kluczowego w Scali? Dlaczego kompilator nie może traktować wszystkichval
tak samo jakfinal val
s?