1

Я написал кусок кода:Java - статическая инициализация

public class Child{ 
int y ; 
private static final int z = getZ(); 

static { 
    System.out.println("The value of z is "+z); 
} 

public int getX(){ 
    System.out.println("get x"); 
    return 10; 
} 

public int getY(){ 
    Child ch = new Child(); 
    System.out.println("get y"); 
    ch.y = getX(); 
    return y; 
} 

public static int getZ(){ 
    System.out.println("get z"); 
    return new Child().getY(); 
} 

public Child(){ 
    System.out.println("Child constructor"); 
} 


public static void main(String...args){ 
    Child ch = new Child(); 
    System.out.println("the value of z in main is "+z); 
} 
} 

И выход:

прибудет г
Детский конструктор
Детского конструктор
прибудет у
прибудут х
Значение z равно 0
Детский конструктор
Значение z в главном 0

Может ли кто-нибудь объяснить мне, почему значение z равно 0, а не 10?

EDIT: - Спасибо всем, я получил ответ на свой первый вопрос. Я все еще сомневаюсь, насколько я знаю, статические блоки выполняются после загрузки класса и до того, как будет создан экземпляр первого объекта класса. Ну, тогда SOP («Значение z» + z) должно быть выполнено до SOP («Конструктор ребенка»)! Не так ли?

+2

Что вы видите, когда вы пошагово ваша программа в отладчике? –

ответ

7

Посмотрите на GetY():

public int getY(){ 
    Child ch = new Child(); 
    System.out.println("get y"); 
    ch.y = getX(); 
    return y; 
} 

Первые три строки не имеют никакого отношения - они не меняют значения y в этот экземпляр, который получает то, что возвращается.

Вы создаете огромное количество бессмысленных объектов в откровенно спагетти-коде, вызываемом при инициализации того же класса, который вы создаете экземпляры. Я предлагаю вам попытаться сохранить код лот проще этого. Статические инициализаторы следует избегать, где можно начинать, не говоря уже о тех, которые идут по домам, чтобы не делать никакой полезной работы.

+0

менее 3 минут .. быстрый catch! – Jayy

+0

Большое спасибо.Я просто пытался понять концепцию статической инициализации, написав этот пример кода. Пропустил тот факт, что я возвращаю это. Я и не ch.y. – NINCOMPOOP

5

потому что getY() устанавливает ch.y на 10, но возвращает значение this.y.

2

В GetY вы возвращаете this.y, который никогда не устанавливается.

2

В getY() вы вернули неинициализированную переменную y вместо экземпляра Child ch.

1

Его потому, что внутри метода getY() вы создаете новый объект CHild, и вы назначаете 10 этому экземпляру переменной y и когда вы возвращаете y, который будет текущей переменной экземпляра y. Надеюсь, это объяснит.

0

К вашему второму пункту статические поля и статические блоки инициализируются/выполняются в текстовом порядке.

Например:

public class StaticTest() 
{ 
    static 
    { 
    System.out.println("s1 in block 1 :" + s1); 
    } 

    private static String s1 = "s1"; 

    static 
    { 
    System.out.println("s1 in block 2 : " + s1); 
    } 

    public static void main(String args[]) 
    { 
    new StaticTest(); 
    } 
} 

Выход этого будет -

s1 в блоке 1:

s1 в блоке 2: s1

+0

Спасибо за ответ, но я знаю, что статические блоки выполняются в текстовом порядке, но если вы видите вывод для этого конкретного фрагмента кода, который я вставил выше, конструктор для класса вызывается дважды до того, как будет выполнен статический блок. Эта аномалия поражает меня. – NINCOMPOOP