Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
568 views
in Technique[技术] by (71.8m points)

java - why static block in child class does not get executed?

here is the code

public class ClassResolution {
static class Parent {
    public static String name;
    static {
        System.out.println("this is Parent");
        name = "Parent";
    }

}

static class Child extends Parent {
    static {
        System.out.println("this is Child");
        name = "Child";
    }

}

public static void main(String[] args) throws ClassNotFoundException {
    System.out.println(Child.name);
}}

what ouput i expect is:

this is Parent
this is Child
Child

but actually is:

this is Parent
Parent

it seems static block in Child class does not get executed, but why? it's anti-intuition, doesn't it?

supplement:
to make it more clear, i list the 2 1 points below:

  1. As @axtavt say, according to JLS 12.4.1, class Child is loaded, but not initialized.
  2. But @Alexei Kaigorodov pointed out, according to jvms-5.5, class Child should be initialized, because of the execution of instruction getstatic on Child class.

what do you think?

supplement2:
@Alexei Kaigorodov has renewed his mind, so it seems no disagreement left. But I think the point of Alexei Kaigorodov is enlightening, so I left it there.

Thank you, everyone.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From JLS 12.4.1:

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.
  • T is a class and a static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the field is not a constant variable (§4.12.4).
  • T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.

As you can see, nothing of these happens in your code (note that name is declared in Parent, not in Child), therefore Child doesn't get initialized and its static block doesn't get executed.

If you do something to trigger initialization of Child, you'll get an expected output:

new Child();
System.out.println(Child.name); 

Note, however, that static fields are not inherited, therefore Child.name and Parent.name actually refer to the same field. That's why it doesn't make much sense to use code similar to your example in practice.

Also note that despite the fact that Child.name actually refers to Parent.name, it's still referenced as Child.name in the bytecode, therefore your code triggers loading of Child, but not its initialization.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...