2016-10-03 3 views
4

Я знаю, что val не является final, если явно не указано так, и использование javap подтверждает, что Scalac не вставляет final в байт-код.Как вал неизменен?

Так что val неизменен просто потому, что компилятор не позволяет нам писать какой-либо код, который пытается его изменить?

+1

Пожалуйста, смотрите [this] (http://stackoverflow.com/a/13428362/1263942) о том, почему 'val' не 'final': они могут быть переопределены –

ответ

8

final и неизменность два ортогональных понятия:

val означает, что вы не можете изменить (мутировать) переменную, присвоив ничего к нему после первоначального объявления:

val x = 1 
x = 2 // error: reassignment to val 

В JVM байткод это осуществляется создание частного члена и добытчика, но не сеттер:

class A { 
    val x = 1 
} 

=> 

// Java equivalent of a generated bytecode 
public class A { 
    private final int x; 
    public int x() { return x; } 
    ... 
} 

final означает, что вы можете» т переопределить val в подклассе:

class A { 
    final val x = 1 
} 

class B extends A { 
    override val x = 2 
} 

// error: overriding value x in class A of type Int(1); 
// value x cannot override final member 

final вызовет ту же ошибку, если вы используете var вместо val.

+0

К сожалению, Java сочетает использование финалистов так, чтобы кто-либо исходящий из Java, скорее всего, будет смущен. – Phasmid

+0

@ Victor, спасибо за комментарий. Поэтому, ставя свою путаницу в приложение «final» с одной стороны, вы отвечаете на мой вопрос о том, как «val» является неизменяемой конструкцией, потому что scalac не позволит нам реализовать «setter» для 'val'? – JamieP

+0

Сам Scalac не реализует сеттер для val. Таким образом, он является фактически неизменным. Окончательные поля Java могут быть мутированы с отражением, если вы достаточно стараетесь. –

Смежные вопросы