2012-04-19 2 views
0

Я знаю, что статические блоки запускаются раньше всего. Но здесь, что происходит при вызове B.test()? Порядок выполнения и установки значений? Позже, когда b1 имеет значение null, все еще, как b1.i оценивает значение 20?Порядок исключения, статические блоки, поля

class B 
{  
    static int i; 
    static { 
     i = 20; 
     System.out.println("SIB"); 
    } 
    static int test() { 
     int i = 24; 
     System.out.println(i); 
     return i; 
    } 
} 

public class Manager { 
    public static void main(String[] arg) { 
     B.test(); 
     B b1 = null; 
     System.out.println(b1.i); 
    } 
} 

Выход:

SIB 
24 
20 
+0

B.test не установлены какие-либо статические или переменные экземпляра, поэтому вызов не будет иметь долгосрочный эффект. (Прочтите его ОЧЕНЬ внимательно.) –

+0

Кстати, это неправильная практика доступа к статическому члену из нестатической ссылки (например, экземпляр b1). – garbagecollector

ответ

3

i является статическим, поэтому b1.i эквивалентно B.i. Просто установка b1 на null не изменяет никаких статических переменных.

Когда вызывается B.test(), сначала загружается класс B и запускаются статические блоки. Затем B.test() создает новую локальную переменную метода с именем i, которая полностью отличается от B.i. Этот новый, локальный i печатается и возвращается. Изменения не внесены в B.i и , конечно, не только потому, что вы создали новую ссылку на объект B, которая была нулевой - это ни на что не повлияло бы.

+0

Спасибо, но когда b1 установлен в null, он должен хранить, ничего не указывать. Должно ли b1.i давать nullPointerException, поскольку b1 ничего не означает, он не будет ссылаться на внутренние значения, такие как i или другие поля? – onlinenaman

+1

Ссылка на статические поля, как если бы они были переменными экземпляра, довольно забавна, но в основном, если вы ссылаетесь на 'instance.staticField', она полностью игнорирует значение' instance', даже если оно равно null. –

1

Но здесь, что происходит при вызове B.test()? Порядок выполнения и установки значений?

Без изменений.

Позже, когда b1 установлен в null, все еще, как b1.i оценивает значение 20?

Поскольку b1 не используется, то поле является статическим, так что вы на самом деле с помощью B.i

5

Значение i здесь

static int i; 
static { 
    i = 20; 
    System.out.println("SIB"); 
} 

установлен в 20 и никогда не изменяется, поэтому, когда вы доступ b1.i, все еще 20.

В вашем методе test() вы используете другую переменную i, которая не имеет отношения к статическому.

1

Что происходит:

  • B.test() называется в первый раз, перед тем как запустить его:
  • Класс B загружается,
  • Статический инициализатор казнены (B.i = 20 теперь)
  • Содержание B.test()
  • (создает локальный метод int i = 24 (который затеняет статическую переменную B.i) и печатает его)
  • b1.i понимается как B.i (который по-прежнему 20) и печатается.
+0

Спасибо, но когда b1 установлен в null, он должен хранить, ничего не указывать. Должно ли b1.i давать nullPointerException, поскольку b1 ничего не означает, он не будет ссылаться на внутренние значения, такие как i или другие поля? b1.i -> null.i? – onlinenaman

+1

Нет, вы получаете доступ к статической переменной, которая хранится в классе, а не в экземпляре. Компилятор фактически просто смотрит на класс 'b1' и выясняет, что вы обращаетесь к' B.i'. Он никогда не пытается что-либо сделать с экземпляром. – trutheality

1
What you did:    What really happened: 
B.test()     - static block of class B is run, static i set to 20, SIB is displayed 
          - test method is called, local property i set to 24, 24 is displayed 
b1 = null     - set reference for b1 to null. Note that this doesn't change the value of class B's static properties 
System.out.println(b1.i) - b1 is still Class B. It doesn't matter what its current reference is. Static i for class B is still 20, 20 is displayed 
Смежные вопросы