Eu costumava pensar assim private val
e private final val
são os mesmos, até que vi a seção 4.1 na Referência de Scala:
Uma definição de valor constante está na forma
final val x = e
onde e é uma expressão constante (§6.24). O modificador final deve estar presente e nenhuma anotação de tipo pode ser fornecida. As referências ao valor constante x são tratadas como expressões constantes; no código gerado, eles são substituídos pelo lado direito da definição e.
E eu escrevi um teste:
class PrivateVal {
private val privateVal = 0
def testPrivateVal = privateVal
private final val privateFinalVal = 1
def testPrivateFinalVal = privateFinalVal
}
javap -c
resultado:
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
}
O código de byte é exatamente como o Scala Reference disse: private val
não é private final val
.
Por que o scalac não trata apenas private val
como private final val
? Existe alguma razão subjacente?
private
modificador de escopo tem a mesma semântica package private
do Java. Você pode querer dizer private[this]
.
private
quer dizer que só é visível para instâncias desta classe, private[this]
apenas esta instância - exceto para instâncias da mesma classe , private
não permite que ninguém (incluir do mesmo pacote) acesse o valor.
val
já é imutável, por que precisamos dafinal
palavra-chave em Scala? Por que o compilador não pode tratar todos osval
s da mesma maneira quefinal val
s?