我试图用静态块这样的:
我叫一个基类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
。 有人可以解释这种现象? 另外,如果我想我的派生类的静态变量设置的值我怎么能做到这一点?
我认为。 你不叫任何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中声明的静态字段用于和场不是一个常数变量(§4.12.4)。
•T是顶层类(第7.6节),并且断言语句(§14.10)词法嵌套在T(§8.1.3)被执行。
静态初始化块不运行,直到类被初始化。 见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.taxi是在课堂超级其实声明的字段的引用,并且不会触发类子的初始化。
有单拷贝myVar
和双方父母和子女类将共享相同的。 直到除非子类得到initilized。
这里是链接到Java规范 - 部分关于静态初始化8.7会谈。 它提供了有关他们应该如何运作以及良好的细节中,他们被调用的顺序。 http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.7
当我们这样做
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
这意味着派生类的静态块不执行.. !!