NPE после назначения объекта - Порядок инициализацииJAVA

Программисты JAVA общаются здесь
Anonymous
NPE после назначения объекта - Порядок инициализации

Сообщение Anonymous »

setup < /h2>
Я недавно наткнулся на интересную ситуацию по теме порядка выполнения и поведения на заданиях переменных. Посмотрите на следующий фрагмент: < /p>

Код: Выделить всё

static class Foo {
int x = 0;
Foo() {}
}

static Foo foo = null;

public static void main(String[] args) {
System.out.println("Before foo: " + foo);
foo.x = setupFoo();
System.out.println("After foo.x: " + foo.x);
}

static int setupFoo() {
foo = new Foo();
foo.x = 1;
System.out.println("Setup foo.x: " + foo.x);
return 2;
}
< /code>
Выход: < /p>
Before foo: null
Setup foo.x: 1
Exception in thread "main" java.lang.NullPointerException:
Cannot assign field "x" because "Test.foo" is null
(выполнено на OpenJDK Temurin-21.0.1+12)
наблюдение
Теперь я бы ожидал, что это будет сразу же на Foo.x = Setupfoo () , потому что Foo wo Code> wonto what yullo what yullo what yullo what yullo> wo nuully , потому что foo no what nut outaly , потому что Foo wom Code wone> nuulatom Вообще не бросается, потому что setupfoo () правильно настроена экземпляры foo = new foo () .
Но по какой -то причине он делает микс. Он входит в метод, несмотря на то, что Foo Null , когда foo.x = setupfoo () , затем полностью проходит через setupfoo () , что будет настроено правильно . Но затем, возвращаясь к Main , он сбои, говоря, что foo - это null - что это было изначально, но больше не является. Какие части в JLS приходят здесь?

Код: Выделить всё

javap -v
):

Код: Выделить всё

public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: getstatic     #7          // Field foo:LTest$Foo;
3: invokestatic  #13         // Method setupFoo:()I
6: putfield      #17         // Field Test$Foo.x:I
9: return
LineNumberTable:
line 10: 0
line 11: 9

static int setupFoo();
descriptor: ()I
flags: (0x0008) ACC_STATIC
Code:
stack=2, locals=0, args_size=0
0: new           #18         // class Test$Foo
3: dup
4: invokespecial #23         // Method Test$Foo."":()V
7: putstatic     #7          // Field foo:LTest$Foo;
10: getstatic     #7           // Field foo:LTest$Foo;
13: iconst_1
14: putfield      #17          // Field Test$Foo.x:I
17: iconst_2
18: ireturn
LineNumberTable:
line 14: 0
line 15: 10
line 16: 17
< /code>
Если я понимаю это правильно, кажется, что поведение в основном объясняется этим битом здесь: < /p>
0: getstatic     #7   // Field foo:LTest$Foo;
3: invokestatic  #13  // Method setupFoo:()I
6: putfield      #17  // Field Test$Foo.x:I
который:
  • Получает ссылку на поле foo для назначения (в настоящее время null )
  • Затем вызовы setupfoo () и процессы, выполняя Fool nonlu foo.x Но ссылка foo была помещена в стек перед вызовом метода, так что он все еще null в этом контексте


Подробнее здесь: https://stackoverflow.com/questions/796 ... tion-order

Вернуться в «JAVA»