近日在《深入Java虚拟机》7.1中看到 如下一段话
"任何一个类的初始化都要求它的超类在此之前已经初始化了。以此类推,该规则就意味着某个类的所有祖先类必须在该类之前被初始化。然而,对于接口来说,[color=red]这条规则并不适用。只有在某个接口所声明的非常量字段被使用时,该接口才会被初始化[/color],而不因为实现这个接口的子接口或类要初始化而初始化"
为不浪费大家的时间,我再三确对了红色部分的内容(不排除书印刷错误)。
这里我就看不懂啦 产生2个疑问
1.接口中的“非常量字段被使用时”,我所了解到的是接口中都是 final static 的 即使不写
2.“该接口才会被初始化”,我开始以为是说 他的实现或者什么的,但后面有句“而不因为实现这个接口的子接口或类要初始化而初始化”。
实在是不明白,望指点!
顶楼引用的[url=http://www.artima.com/insidejvm/ed2/lifetype.html]那段话的原文[/url]是:
[quote]As mentioned in the previous list, initialization of a class requires prior initialization of its superclass. Applied recursively, this rule means that all of a class's superclasses must be initialized prior to the initialization of the class. The same is not true, however, of interfaces. An interface is initialized only because a non-constant field declared by the interface is used, never because a subinterface or class that implements the interface needs to be initialized. Thus, initialization of a class requires prior initialization of all its superclasses, but not its superinterfaces. Initialization of an interface does not require initialization of its superinterfaces.[/quote]
这本书的中文翻译本来就很糟糕,看不懂的时候请参考原文。
顶楼引用的这段翻译倒没什么大问题。描述的状况就是一个类在进行初始化之前,其超类必须已经完成初始化(否则子类的初始化就会触发超类的初始化),但它所实现的接口却不须要已经完成初始化。一个接口在初始化的时候也不要求其超接口已经完成初始化。
这是由于接口只在它所声明的非常量域被使用时才必须初始化。没错,接口上的成员都是隐式声明为public,接口上的域都隐式声明为static final,但为这些域提供值的初始化表达式却不一定要是“常量表达式”。请参考[url=http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#18349]JVM规范第2版2.13.3.1 Interface (Constant) Fields小节[/url]。
例如
[code="java"]public interface IFoo {
int INIT_TIME = System.nanoTime(); // 非常量表达式初始化的域
int ONE = 1; // 常量表达式初始化的域
}
《深入Java虚拟机》7.1节所说的“非常量字段”指的就是这种接口上使用非常量表达式初始化的域。
之所以会引起混淆是因为Java语言中没有区分编译时常量与运行时不变量,两者都使用final关键字来修饰。在C#里这两个概念就被清晰的分开,编译时常量用const、运行时不变量用readonly关键字来修饰。顶楼所引用的文字说的就是运行时不变量,而楼主心里想的是编译时常量。
要注意的是 [quote]字段并不是接口的一部分,而是保存于那个接口的static存储区域中[/quote]
[color=indigo]我个人认为是这样的 它说的 接口初始化 应该是指 用到接口里的常量 在没有枚举类型的时候 咱们不也经常这么用么.
平常接口的实现类,只是按照这个接口 来实现自己的方法 而没有把接口实例化。[/color]