Lo pensavo private vale private final valsono la stessa cosa, finché non ho visto la sezione 4.1 in Scala Reference:
Una definizione di valore costante è della forma
final val x = edove 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 valnon lo è private final val.
Perché lo scalac non tratta solo private valcome private final val? C'è una ragione di fondo?
privatemodificatore di ambito ha la stessa semantica package privatedi Java. Potresti voler dire private[this].
privatesignifica che è visibile solo alle istanze di questa classe, private[this]solo questa istanza - ad eccezione delle istanze della stessa classe , privatenon consente a nessuno (include dallo stesso pacchetto) di accedere al valore.
valè già immutabile, perché abbiamo bisogno dellafinalparola chiave in Scala? Perché il compilatore non può trattare tuttivali messaggi allo stesso modo difinal vals?