34

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

我有一个名为的基类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 0这会按照我的预期打印输出10 0。有人可以解释这种行为吗?另外,如果我希望我的派生类设置静态变量的值,我该如何实现?

4

5 回答 5

24

我认为。您不调用任何Derived属性(myVar属于Base,不属于Derived)。并且 java 没有从Derived. 如果您添加一些静态字段Derived并访问它,那么 java 会执行所有静态块。

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 节)。

于 2012-05-22T08:57:48.923 回答
6

静态初始化程序块在类初始化之前不会运行。请参阅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 类的初始化。

于 2012-05-22T08:52:58.737 回答
1

有一个副本,myVar父类和子类将共享相同的副本。直到和除非子类被初始化。

于 2012-05-22T08:51:06.490 回答
1

当我们这样做

class Base {

    public static int myVar = 0;
    static {
        System.out.println("Base");
    }
}

class Derived extends Base {

    static {
        System.out.println("Derived");
        Base.myVar = 9;

    }
}

public class StaticBlock {

    public static void main(String[] args) {

        System.out.println(Base.myVar);
        System.out.println(Derived.myVar);
    }
}

输出将是 Base 0 0

这意味着派生类的静态块没有执行..!!

于 2012-08-07T07:56:42.707 回答
0

这是 Java 规范的链接 - 第 8.7 节讨论了静态初始化程序。它提供了有关它们应该如何运行以及它们被调用的顺序的详细信息。http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.7

于 2012-05-22T08:54:25.787 回答