使用子类名称访问父类静态字段不会加载子类?

6
class A {
    static int super_var = 1;
    static {
        System.out.println("super");
    }
}

class B extends A {
    static int sub_var = 2;
    static {
        System.out.println("sub");
    }    
}
public class Demo{
    public static void main(String []args){
        System.out.println(B.super_var);
    }
}

输出结果是:
super
1

这意味着子类不会加载或者有其他的事情吗?它是如何工作的?

我不明白你的问题。你期望什么输出? - Rohit Jain
3
我假设对于 B 的静态初始化程序应被调用。 - Boris the Spider
@boris 是的,这正是我所期望的。 - Kalhan.Toress
2个回答

12
当你通过子类引用访问超类的static字段时,只有声明该字段的类将被加载和初始化,这种情况下是A。这在JLS §12.4.1 - 当初始化发生时中有说明:

static字段(§8.3.1.1)的引用仅导致实际声明它的类或接口的初始化,即使它可能通过子类、子接口或实现接口的类的名称引用。

重点在我身上。

因此,在您的代码中,类B甚至不会被初始化,因此其static块也不会执行。

0

查看这个问题的答案:Java中静态初始化块的运行顺序是什么?

静态块只有在访问类时才会被调用(无论是创建实例还是访问成员字段或静态方法)。然而,您仅访问了类A的成员,因此没有理由初始化类B。只有当您访问该类的成员(字段或静态方法或从类B创建一个实例)时,才会调用B的静态初始程序。

原因是在访问其成员之前,类B不需要初始化。因为A不知道B(无法访问它),所以在那个阶段B没有初始化的必要。

当您访问B.sub_var时,将执行B的静态初始化程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接