Если посмотреть на декомпилированном байт кода Foo.class
, вы увидите следующее: сам
- Класс конструктор только присваивает значение 10 (bipush и putfield). Конструктор класса сначала не назначает 0, а затем 10.
- VM будет иметь значение по умолчанию 0 для поля всякий раз, когда к нему обращаются - независимо от того, из какого кода. Таким образом, это значение по умолчанию не будет отображаться нигде - по крайней мере, не в байт-коде класса или других классов, которые обращаются к полю, например, путем отражения. Первоначальные значения по умолчанию запекаются в виртуальную машину.
- В явной настройке по умолчанию будет создан другой байт-код, см. Второй пример.
.
public class Foo {
private int var;
public Foo();
0 aload_0 [this]
1 invokespecial java.lang.Object() [10]
4 aload_0 [this]
5 bipush 10
7 putfield Foo.var : int [12]
10 return
Если вы пишете следующее:
public class Foo {
private int var = 0;
public Foo() {
var = 20;
}
}
байт-код будет:
0 aload_0 [this]
1 invokespecial java.lang.Object() [10]
4 aload_0 [this]
5 iconst_0
6 putfield Foo.var : int [12]
9 aload_0 [this]
10 bipush 20
12 putfield Foo.var : int [12]
15 return
Следующий пример показывает, что доступ к переменной будет еще не приводит к заданию из любое значение:
public class Foo {
private int var;
public Foo() {
System.out.println(var);
var=10;
}
}
Этот код будет печатать 0
потому getField Foo.var
на опкодом 8 будет толкать «0» в стек операндов:
public Foo();
0 aload_0 [this]
1 invokespecial java.lang.Object() [10]
4 getstatic java.lang.System.out : java.io.PrintStream [12]
7 aload_0 [this]
8 getfield Foo.var : int [18]
11 invokevirtual java.io.PrintStream.println(int) : void [20]
14 aload_0 [this]
15 bipush 10
17 putfield Foo.var : int [18]
20 return
Ну, это не совсем так. Поскольку поле является частным, и не определены никакие аксессоры, кто говорит, что это невозможно оптимизировать? –
@Axel: потребовалось бы больше работы, чтобы выяснить, какие места памяти в распределении не нужно обнулять, чем просто нулевое целое, поэтому оптимизация будет иметь неприятные последствия. Также рассмотрим случай, когда конструктор выбирает частное поле с использованием отражения. Это случай сомнительной реальной ценности, но он демонстрирует одну из причин того, почему поля ведут себя так, как они делают во время построения объекта - даже необходимо определить случаи сомнительной ценности реального мира. Если бы это было поле ссылочного типа, оставив мусор там, так как оптимизация была бы серьезной угрозой безопасности ... – cdhowie
Хорошо, давайте не будем путать вещи здесь. Компилятор выполняет поиск в _compile time_, чтобы сохранить инициализацию в _run time_ –