首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java类v/s接口的初始化

Java类v/s接口的初始化
EN

Stack Overflow用户
提问于 2011-01-30 16:22:51
回答 3查看 6.8K关注 0票数 9

以下是java类和接口的initialization的概念:

我在下面提到的书中读了以下一句:

接口的初始化仅仅是因为使用了接口声明的非常数字段,而不是因为实现接口的子接口或类需要初始化。 但是,当我们初始化任何java类时,情况并非如此。因此,类的初始化需要预先初始化它的所有超类,而不是它的超级接口。 接口的初始化不需要初始化它的超级接口。

我的问题是为什么会这样?

任何帮助都将不胜感激!

谢谢

PS : Book --比尔·文纳斯的“Java虚拟机内部”(第7章-类的LifeTime )

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-30 16:36:38

在接口中唯一可以声明的是方法签名和常量字段。后者可以使用常量值(即字符串文本、整数等,可能是某种组合)或使用非常量值(即方法调用)初始化。因此,如果接口没有任何非常量字段,则不需要初始化--在编译时就知道了一切。如果程序使用的是非常量字段,则必须运行初始化代码以确保为这些字段分配值。

希望这能有所帮助。

P.S.:如果有人想要完整的阅读,这一章可以在网上找到这里

票数 6
EN

Stack Overflow用户

发布于 2011-01-30 16:44:44

引用Java语言规范§12.4.1:

类或接口类型T将在第一次出现以下任何一种情况之前立即初始化:

  • T是一个类,并创建了一个T的实例。
  • T是一个类,调用T声明的静态方法。
  • 指定一个由T声明的静态字段。
  • 使用由T声明的静态字段,并且对该字段的引用不是编译时常数(§15.28)。对编译时常量的引用必须在编译时解析为编译时常量值的副本,因此这样的字段的使用不会导致初始化。

类类和包java.lang.reflect中某些反射方法的调用也会导致类或接口初始化。在任何其他情况下都不会初始化类或接口。

这里的意图是,类或接口类型有一组初始化器,使其处于一致状态,并且该状态是其他类观察到的第一个状态。

票数 1
EN

Stack Overflow用户

发布于 2011-01-30 21:24:28

有意思的。让我们看看为什么超类必须在子类之前被初始化。

代码语言:javascript
复制
class A
    static x = DB.insert(1,...);
class B extends A
    static y = DB.select(1);

超类的静态初始化程序可能会导致编译器看不到的一些副作用,子类可能依赖于这种副作用。

但是,相同的参数可以应用于超级接口。我看不出Java为什么不急切地初始化超级接口的原因。任何一个人都可以猜测软的理由。

给出规则,我们必须小心接口中的字段初始化:

  1. 最好在接口中没有任何字段。
  2. 否则,字段最好仅为编译时间常数。
  3. 否则,字段初始化最好没有任何副作用。
  4. 否则,副作用只能通过字段本身访问。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4843950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档