Solía pensar eso private valy private final valson lo mismo, hasta que vi la sección 4.1 en Scala Reference:
Una definición de valor constante tiene la forma
final val x = edonde e es una expresión constante (§6.24). El modificador final debe estar presente y no se puede dar ninguna anotación de tipo. Las referencias al valor constante x se tratan en sí mismas como expresiones constantes; en el código generado se reemplazan por el lado derecho de la definición e.
Y he escrito una prueba:
class PrivateVal {
private val privateVal = 0
def testPrivateVal = privateVal
private final val privateFinalVal = 1
def testPrivateFinalVal = privateFinalVal
}
javap -c salida:
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
}
El código de bytes es tal como lo dijo Scala Reference: private valno lo es private final val.
¿Por qué scalac no trata simplemente private valcomo private final val? ¿Existe alguna razón subyacente?

valya es inmutable, ¿por qué necesitamos lafinalpalabra clave en Scala? ¿Por qué el compilador no puede tratar todos los correos electrónicos devalla misma manera quefinal vallos correos electrónicos?privatemodificador de alcance tiene la misma semántica quepackage privateen Java. Puede querer decirprivate[this].privatesignifica que solo es visible para instancias de esta clase,private[this]solo esta instancia, excepto para instancias de la misma clase ,privateno permite que nadie (incluido del mismo paquete) acceda al valor.Respuestas:
Entonces, esto es solo una suposición, pero fue una molestia constante en Java que las variables estáticas finales con un literal en el lado derecho se incluyan en el código de bytes como constantes. Eso engendra un beneficio de rendimiento seguro, pero hace que la compatibilidad binaria de la definición se rompa si la "constante" alguna vez cambia. Al definir una variable estática final cuyo valor podría necesitar cambiar, los programadores de Java tienen que recurrir a trucos como inicializar el valor con un método o constructor.
Un val en Scala ya es final en el sentido de Java. Parece que los diseñadores de Scala están usando el modificador redundante final para significar "permiso para incorporar el valor constante". Así que los programadores de Scala tienen control total sobre este comportamiento sin recurrir a hacks: si quieren una constante en línea, un valor que nunca debería cambiar pero que es rápido, escriben "final val". si quieren flexibilidad para cambiar el valor sin romper la compatibilidad binaria, simplemente "val".
fuente
private valaprivate final val?valen su segundo párrafo?Creo que la confusión aquí surge al combinar la inmutabilidad con la semántica de final.
vals se pueden anular en clases secundarias y, por lo tanto, no se pueden tratar como finales a menos que se marquen explícitamente como tales.@Brian El REPL proporciona un alcance de clase a nivel de línea. Ver:
fuente
private val. ¿Se puede anular?