Früher habe ich das gedacht private val
und private final val
bin es auch, bis ich Abschnitt 4.1 in Scala Reference sah:
Eine konstante Wertedefinition hat die Form
final val x = e
wobei e ein konstanter Ausdruck ist (§6.24). Der letzte Modifikator muss vorhanden sein und es dürfen keine Typanmerkungen angegeben werden. Verweise auf den konstanten Wert x werden selbst als konstante Ausdrücke behandelt; im generierten Code werden sie durch die rechte Seite der Definition ersetzt. e.
Und ich habe einen Test geschrieben:
class PrivateVal {
private val privateVal = 0
def testPrivateVal = privateVal
private final val privateFinalVal = 1
def testPrivateFinalVal = privateFinalVal
}
javap -c
Ausgabe:
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
}
Der Bytecode ist genau so, wie Scala Reference sagte: private val
nicht private final val
.
Warum behandelt Scalac nicht einfach private val
so private final val
? Gibt es einen Grund dafür?
private
Bereichsmodifikator dieselbe Semantik wie package private
in Java hat. Sie können sagen private[this]
.
private
bedeutet, dass es nur für Instanzen dieser Klasse sichtbar ist, private[this]
nur für diese Instanz - mit Ausnahme von Instanzen derselben Klasse kann private
niemand (einschließlich aus demselben Paket) auf den Wert zugreifen.
val
bereits unveränderlich ist, warum brauchen wir dasfinal
Schlüsselwort überhaupt in Scala? Warum kann der Compiler nicht alleval
s genauso behandeln wiefinal val
s?