具有继承的静态块的行为

2022-09-01 06:59:54

我正在尝试使用这样的静态块:

我有一个名为Base.java

public class Base {

    static public int myVar;

}

和一个派生类:Derived.java

public class Derived extends Base {

    static
    {
        Base.myVar = 10;
    }
}

我的函数是这样的:main

public static void main(String[] args)  {
    System.out.println(Derived.myVar);
    System.out.println(Base.myVar);
}

这将打印出放,如我所期望的那样。有人能解释这种行为吗?另外,如果我希望我的派生类设置静态变量的值,我该如何实现呢?0 010 0


答案 1

据我所知。不调用任何属性(属于 ,而不是 )。而且 java 没有从 运行静态块。如果您向其中添加一些静态字段并访问它,则java将执行所有静态块。DerivedmyVarBaseDerivedDerivedDerived

class Base {

    static public int myVar;

}


class Derived extends Base {

    static public int myVar2;

    static
    {
        Base.myVar = 10;
    }
}


public class Main {
    public static void main( String[] args ) throws Exception {
        System.out.println(Derived.myVar2);
        System.out.println(Base.myVar);
    }
}

从java规范中,当类被初始化时(并且静态块被执行):

12.4.1 初始化时 类或接口类型 T 将在首次出现以下任何一项之前立即初始化:

• T 是一个类,并创建了 T 的实例。
• T 是一个类,调用 T 声明的静态方法。
• 分配由 T 声明的静态字段。
• 使用 T 声明的静态字段,并且该字段不是常量变量 (§4.12.4)。
• T 是顶级类 (§7.6),并执行词法嵌套在 T (§8.1.3) 中的断言语句 (§14.10)。


答案 2

在初始化类之前,不会运行静态初始值设定项块。请参阅 Java 语言规范第 8.7 段(静态初始值设定项)和 12.4.1(发生初始化时):

在类中声明的静态初始值设定项在类初始化时执行 (§12.4.2)。与类变量 (§8.3.2) 的任何字段初始值设定项一起,静态初始值设定项可用于初始化类的类变量。

下面是一个直接来自 JLS 12.4.1 的类似示例:

class Super {
  static int taxi = 1729;
}
class Sub extends Super {
  static { System.out.print("Sub "); }
}
class Test {
  public static void main(String[] args) {
    System.out.println(Sub.taxi);
  }
}

此程序仅打印:

1729

因为类 Sub 从未初始化;对 Sub.taxi 的引用是对在类 Super 中实际声明的字段的引用,不会触发类 Sub 的初始化。


推荐