Eu costumava pensar assim private vale private final valsã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 = eonde 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 valnão é private final val.
Por que o scalac não trata apenas private valcomo private final val? Existe alguma razão subjacente?
privatemodificador de escopo tem a mesma semântica package privatedo Java. Você pode querer dizer private[this].
privatequer dizer que só é visível para instâncias desta classe, private[this]apenas esta instância - exceto para instâncias da mesma classe , privatenão permite que ninguém (incluir do mesmo pacote) acesse o valor.
valjá é imutável, por que precisamos dafinalpalavra-chave em Scala? Por que o compilador não pode tratar todos osvals da mesma maneira quefinal vals?