问题描述
class NewParent { static int hoursOfSleep = (int) (Math.random() * 3.0); static { System.out.println("NewParent was initialized."); }}class NewbornBaby extends NewParent { static int hoursOfCrying = 6 + (int) (Math.random() * 2.0); static { System.out.println("NewbornBaby was initialized."); }}class Example2 { public static void main(String[] args) { int hours = NewbornBaby.hoursOfSleep; System.out.println(hours); static { System.out.println("Example2 was initialized."); }}NewbornBaby调用从NewParent继承来的hoursOfSleep,说明NewbornBaby类已经主动使用,但是为什么NewbornBaby类没有被初始化
解决方案
请把《深入java虚拟机》第二版翻到162页:代码上面的那段,有这样说:使用一个非常量的静态字段只有当类或者接口的却声明了这个字段时才是主动使用
解决方案二:
首先,因为 hoursOfSleep 是父类的,子类从父类中继承了该字段(这个你是明白的),而之所以NewbornBaby.hoursOfSleep; 它没有让子类初始化,是因为它相当于NewParent.hoursOfSleep; 所以,父类被初始化了,而子类并没有被初始化
解决方案三:
hoursOfSleep是非常量静态字段,它继承自NewParent,并不是NewbornBaby类声明的,所以不符合主动使用的要求
解决方案四:
hoursOfSleep是非常量静态字段,它继承自hoursOfSleep,并不是NewbornBaby类声明的,所以不符合主动使用的要求
解决方案五:
只有六种活动被认为是主动使用:1、创建类的新实例2、调用类中声明的静态方法3、操作类或者接口中声明的非常量静态字段4、调用JAVA API中特定的反射方法5、初始化一个类的子类6、指定一个类作为虚拟机启动时初始化的类
解决方案六:
static声明的变量是类变量,与对象的加载初始化没太大关系,你可以直接这么调用,而这个类变量其实是父类的,不是自己的。
解决方案七:
引用NewbornBaby调用从NewParent继承来的hoursOfSleep,说明NewbornBaby类已经主动使用,但是为什么NewbornBaby类没有被初始化 类变量是不能继承的,实际上是访问父类的类变量,只会导致父类初始化。