Раньше я думал, что это одно private val
и то private final val
же, пока не увидел раздел 4.1 в Справочнике по Scala:
Определение постоянного значения имеет вид
final val x = e
где e - постоянное выражение (§6.24). Должен присутствовать последний модификатор, а аннотация типа не может быть дана. Ссылки на постоянное значение x сами по себе рассматриваются как постоянные выражения; в сгенерированном коде они заменяются правой частью определения e.
И я написал тест:
class PrivateVal {
private val privateVal = 0
def testPrivateVal = privateVal
private final val privateFinalVal = 1
def testPrivateFinalVal = privateFinalVal
}
javap -c
вывод:
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
}
Байт-код такой же, как и в Scala Reference: private val
нет private final val
.
Почему к скальаку не относятся просто private val
так private final val
? Есть ли основная причина?
val
уже является неизменяемым, зачем нам вообще нужноfinal
ключевое слово в Scala? Почему компилятор не может обрабатывать все такval
же, какfinal val
s?private
модификатор области имеет ту же семантику, что иpackage private
в Java. Вы можете сказатьprivate[this]
.private
означает, что он виден только экземплярам этого класса,private[this]
только этот экземпляр - за исключением экземпляров того же класса ,private
не позволяет никому (включая из того же пакета) получить доступ к значению.Ответы:
Итак, это всего лишь предположение, но в Java было постоянное раздражение, что конечные статические переменные с литералом с правой стороны встраиваются в байт-код как константы. Это несомненно дает выигрыш в производительности, но приводит к нарушению двоичной совместимости определения, если "константа" когда-либо изменяется. При определении конечной статической переменной, значение которой может потребоваться изменить, Java-программисты должны прибегать к хитростям, таким как инициализация значения с помощью метода или конструктора.
Val в Scala уже является окончательным в смысле Java. Похоже, что дизайнеры Scala используют избыточный модификатор final для обозначения «разрешения встроить постоянное значение». Таким образом, программисты Scala имеют полный контроль над этим поведением, не прибегая к хитростям: если им нужна встроенная константа, значение, которое никогда не должно изменяться, но быстро, они пишут «final val». если они хотят гибкости для изменения значения без нарушения двоичной совместимости, просто «val».
источник
private val
наprivate final val
?val
во втором абзаце?Я думаю, что путаница здесь возникает из-за смешения неизменяемости с семантикой final.
val
s могут быть переопределены в дочерних классах и, следовательно, не могут рассматриваться как final, если явно не отмечены как таковые.@Brian REPL обеспечивает область видимости класса на уровне строки. Видеть:
источник
private val
. Можно ли его переопределить?