2014-03-05 58 views
0
class Super { static String ID = "SUPER_ID"; } 

class SubClass extends Super{ 
    static { System.out.print("In SubClass"); } 
} 

class Test{ 
    public static void main(String[] args) { 
    System.out.println(SubClass.ID); 
    } 
} 

为什么我已经在输出为什么静态块不能在调用对象中加载?

SUPER_ID 

代替

In SubClass 
SUPER_ID 


子类将在对象的第一呼叫被加载。那么为什么 static init块不能执行? 谢谢。

+0

您还没有初始化'SubClass',你指的是'static'场(它'延伸Super')。 – Maroun

+0

@MarounMaroun但如果我有包含'静态'常量的接口,我第一次调用时,我的接口加载到'JVM'中。有什么区别? –

回答

1

因为在编译时本身,SubClass.ID将由编译器更改为Super.ID。 就像@Kugathasan Abimaran所说的,继承和静态是两回事。

例子:

public class SampleClass { 
    public static void main(String[] args) { 
     System.out.println(SubClass.ID); 
     System.out.println(SubClass.i); 
    } 
} 

class Super { 
    static String ID = "SUPER_ID"; 
} 

class SubClass extends Super { 
    static { 
     System.out.println("In SubClass"); 
    } 

    static int i; 
} 

Output : 
SUPER_ID 
In SubClass // only when accessing a variable of subclass, the class will be initialized. 
0 
+0

很棒的回答。谢谢! –

+0

继承与静态成员?错误的措辞。 –

+0

@KugathasanAbimaran - 我的意思是说 - 该类尚未加载到JVM中,并且在编译期间,SubClass.ID将被引用为Super.ID – TheLostMind

0

你的类不被类加载器加载,因为它不是在你的Test类使用,如果你想加载它只是添加语句Class.forName("SubClass");在您的测试类之后你可以看到你所期望的结果。你也可以使用类加载器而不是Class.forName加载这个类。

class Test{ 
    public static void main(String[] args) { 
    Class.forName("SubClass"); 
    //Thread.currentThread().getContextClassLoader().loadClass("SubClass"); 
    System.out.println(SubClass.ID); 
    } 
} 
0

根据Java语言规范:

静态字段的引用仅引起类或 接口,实际上声明它,即使它可能通过 被称为初始化子类的名称,子接口或实现接口的类。

More info

相关问题