具有继承的静态块的行为

时间:2012-05-22 08:37:00

标签: java inheritance static static-block

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

我有一个名为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。有人可以解释这种行为吗?另外,如果我希望我的派生类设置静态变量的值,我该如何实现呢?

5 个答案:

答案 0 :(得分:22)

据我了解。您不会调用任何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节)。

答案 1 :(得分:6)

在初始化类之前,不会运行静态初始化程序块。参见Java Language Specification第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类的初始化。

答案 2 :(得分:1)

myVar只有一个副本,父类和子类都会共享相同的副本。 直到并且除非儿童课程被启动。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

当我们做的时候

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

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