Lo pensavo private val
e private final val
sono la stessa cosa, finché non ho visto la sezione 4.1 in Scala Reference:
Una definizione di valore costante è della forma
final val x = e
dove e è un'espressione costante (§6.24). Il modificatore finale deve essere presente e non può essere fornita alcuna annotazione di tipo. I riferimenti al valore della costante x vengono trattati come espressioni costanti; nel codice generato sono sostituiti dal lato destro della definizione e.
E ho scritto un test:
class PrivateVal {
private val privateVal = 0
def testPrivateVal = privateVal
private final val privateFinalVal = 1
def testPrivateFinalVal = privateFinalVal
}
javap -c
produzione:
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
}
Il codice byte è proprio come dice Scala Reference: private val
non lo è private final val
.
Perché lo scalac non tratta solo private val
come private final val
? C'è una ragione di fondo?
private
modificatore di ambito ha la stessa semantica package private
di Java. Potresti voler dire private[this]
.
private
significa che è visibile solo alle istanze di questa classe, private[this]
solo questa istanza - ad eccezione delle istanze della stessa classe , private
non consente a nessuno (include dallo stesso pacchetto) di accedere al valore.
val
è già immutabile, perché abbiamo bisogno dellafinal
parola chiave in Scala? Perché il compilatore non può trattare tuttival
i messaggi allo stesso modo difinal val
s?