2012-03-30 3 views
0
public class StaticTest { 

    private static StaticTest stObj=new StaticTest(); 
    private static int VAR1=10; 
    private static final int VAR2=20; 

    public StaticTest() { 

     System.out.println("Var1 : "+VAR1); 
     System.out.println("Var2 : "+VAR2); 
    } 

    public static void main(String[] args) { 
     System.out.println("VAR1 after constrution : "+StaticTest.VAR1); 
    } 

} 

Выход:разница Java между статической и окончательной статической инициализации переменной

Var1: 0 Переменная2 20 VAR1 после constrution: 10

Почему это различное поведение для VAR1 и var2?

+1

VAR2 является постоянным значением, но VAR1 является простой статической переменной. Это означает, что VAR1 будет инициализирован после инициализации stObj. Вот почему VAR1 равен 0 [значение по умолчанию int init] при первом вызове и 10 после второго вызова. – dexametason

ответ

0

VAR2 не может быть изменен один класс инициализирован, в то время как любой экземпляр класса может изменить VAR позже.

Проблема в том, что вы имеете в виду переменную, прежде чем она будет полностью инициализирована.

private static StaticTest stObj=new StaticTest(); 
private static int VAR1=10; 
private static final int VAR2=20; 

Вы создаете экземпляр класса при загрузке самого класса, прежде чем будут инициализированы другие статические элементы.

Проверьте Java Language Specifications for more details (Chapter 12).

(Как правило, создание экземпляра класса в процессе его собственной конструкции приведет к проблемам: вы должны избежать этого.)

+0

Но никто не меняет какую-либо переменную? – amicngh

+0

, по крайней мере, не в коде, который вы указали. –

+1

Переменная 'VAR' изначально' 0', прежде чем она может быть установлена ​​в '10'. –

0

VAR1 можно изменить, VAR2 не можем.

Попробуйте это:

private static int VAR1=10; 
private static final int VAR2=20; 

public static void main(String[] args) { 
    VAR1 = 25; 
    VAR2 = 35; // You'll find a compilation error here. 
} 
3

VAR2 является константой времени компиляции, поэтому его значение «запеченный в» каждому вызывать сайт. Поэтому не имеет значения, что вы используете его, прежде чем вы будете ожидать, чтобы увидеть его инициализированным. Если вы измените его на то, что не является константой в отношении компилятора, например.

private static final int VAR2 = "xyz".length(); 

, то вы увидите такое же поведение, как и для VAR1 (с точки зрения выхода).

Дополнительную информацию о постоянных выражениях см. В section 15.28 of the JLS.

+0

Значит, вы хотите сказать, что во время компиляции VAR2 считается постоянным? – amicngh

+0

@amicngh: Это не вопрос * предположения * - это вопрос следования JLS.Эта переменная является статической и окончательной, она имеет примитивный тип, а выражение инициализации - выражение постоянной времени компиляции; см. http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28 –

+0

@JonSkeet, вы правы, но я думаю, что в этом вопросе есть еще кое-что (относительно порядка инициализации). – Bruno

5

Статические поля инициализируются один за другим в порядке декларации. В вашем конкретном случае вы сначала инициализируете StaticTest stObj. Это выполняется до инициализации VAR1. Таким образом, VAR1 имеет значение по умолчанию при печати.

Однако VAR2 является константой времени компиляции, поэтому компилятор оптимизирует свою инициализацию и сначала инициализируется. Таким образом, одна из переменных инициализируется к тому времени, когда вы вызываете конструктор, а другой - не.

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