【问题标题】:Java Docs says interfaces cannot have fields.Why?Java Docs 说接口不能有字段。为什么?
【发布时间】:2014-05-20 13:09:03
【问题描述】:

我正在阅读this,它明确指出One significant difference between classes and interfaces is that classes can have fields whereas interfaces cannot.这怎么可能,因为Java Docs 也说all fields in interface are public,static and final

【问题讨论】:

  • public static final 字段被视为常量。
  • public static final 不被视为字段,而是static 成员。文档宁愿将 field 称为非静态的。
  • @all 但是public String x="abc" 呢,因为当我在接口中声明它时它不会显示任何编译错误
  • 编译器会为你生成public static final String x = "abc"
  • @LuiggiMendoza 我说的对吗?

标签: java interface


【解决方案1】:

这怎么可能,因为 Java Docs 还说接口中的所有字段都是 publicstaticfinal

来自Java Language Specification. Chapter 9. Interfaces. 9.3. Field (Constant) Declarations(强调我的):

接口主体中的每个字段声明都是隐式publicstaticfinal。允许为此类字段冗余地指定任何或所有这些修饰符。

如果两个或多个(不同的)字段修饰符出现在一个字段声明中,尽管不是必需的,但习惯上它们的出现顺序与上面 ConstantModifier 产生式中显示的顺序一致。子>

这意味着接口中的每个字段都将被视为public 常量字段。如果您添加publicstaticfinal 或其中一些修饰符或一个都不添加,编译器将为您添加它们。这就是隐式的意思。

所以,有这个:

interface Foo {
    String bar = "Hello World";
}

类似于有

interface Foo {
    public String bar = "Hello World";
}

类似于

interface Foo {
    static bar = "Hello World";
}

三个接口将编译成相同的字节码。

另外,请确保接口中的字段声明遵循子注释。这意味着,您不能缩小界面中字段的可见性。这是非法的:

interface Foo {
    //compiler error!
    private String bar = "Hello World";
}

因为bar 不会是public,它违反了接口中字段的标准定义。

【讨论】:

  • 好的,现在我完全理解了。谢谢你这么详细的解释。
【解决方案2】:

static final 字段是一个常量值,存在于类本身中,而不是类的实例中。接口的实例不能有任何字段,即使接口本身可以,甚至在接口本身上,您也仅限于定义常量。

【讨论】:

  • 但是如果我在 java 中声明 public String x="abc 会怎样。
  • 你错了,我在界面中写了public String x="abc,但它仍然没有给我任何错误。你自己试试吧。
  • public String x = "abc" 这是合法的语法。只是当您不自己添加时,编译器会隐式添加static。当然,原因是因为您永远无法实例化接口,并且在其中包含实例字段是没有意义的。
  • @BHeshGurung 最后也是。
  • @BheshGurung 好点,我总是把 static 和 final 放在一起,因为我认为这样更清楚,但你是对的。如果您不手动放入它们,则会假定它们。
【解决方案3】:

当使用new 创建object 时,所有fields 将被初始化为其值或默认值。 由于您无法实例化interface,因此您无法拥有任何fields。 但是你可以在你的interface 中有constants,这就是为什么所有fields 默认都是public static final

jls

【讨论】:

  • 但是如果我在 java 中声明 public String x="abc 会怎样。
  • @Fresher 你会得到编译器错误,因为它不是final
  • @SajanChandran 你会得到编译器错误,因为它不是最终的 false。编译器会为你标记为static final,类似于如果你不声明任何构造函数,为一个类添加一个默认构造函数。
  • @LuiggiMendoza 如果你已经有任何modifier,编译器不会标记static final,它只会在我们声明为String x="abc"时添加。
  • @SajanChandran 检查您在答案中发布的 JLS 链接。
猜你喜欢
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 1970-01-01
相关资源
最近更新 更多