【问题标题】:static public methods and non static default methods in interfaces接口中的静态公共方法和非静态默认方法
【发布时间】:2023-03-26 13:37:01
【问题描述】:

在浏览java 1.8的java.util.Collections接口源码时,我注意到了这一点,

default boolean removeIf(Predicate<? super E> filter) 
{
 ....
}

从 1.8 开始,java 允许接口中的方法定义主体。但是有一些语义上的特殊性;如果该方法是公开的,我也需要将其明确提及为静态,这是可以理解的,但为什么默认情况下不强制执行?事实上,用默认值指定静态会产生错误。这有什么用?

编辑:看到不赞成票的数量,我建议您先尝试一下,然后再难以置信地得出结论

【问题讨论】:

  • 如果方法是公开的,我需要明确提及它也是静态的你确定吗?
  • 是的,我得到一个错误“接口抽象方法不能有主体”
  • 您没有使用 Java 8 进行编译。default 方法不能是 staticdefault 方法隐式为 public
  • 接口中的所有方法声明,包括默认方法,都是隐式公开的没有提及静态。
  • @SotiriosDelimanolis 您在第 9.5 节中引用的第二条 JLS 适用于 成员类型,即嵌套类和接口,这与这里讨论的不同。 9.4 节的引用当然是相关的。

标签: java java-8 default-method


【解决方案1】:

我尝试编译如下测试接口:

public interface TestInterface {
                    void m();
           abstract void am();
           default  void dm() { }
           static   void sm() { }
    public          void pm();
    public abstract void pam(); 
    public default  void pdm() { }
    public static   void psm() { }
}

使用我碰巧在身边的 JDK,即:8、8u5、8u11、8u25、8u40,以及几天前的 jdk9-dev 版本。它在所有这些版本上都成功编译。

正如其他人所指出的,接口中的方法都是公共的,无论是否指定了public。此外,方法可以是抽象的、默认的或静态的,如果没有指定这些方法,则方法是抽象的。 (JLS 9.4) 最后,声明为defaultstatic 的方法必须有一个块{ ... } 作为主体,而抽象方法(无论是否声明)必须有一个分号; 作为主体。 (JLS 9.4.3)

如果该方法是公开的,我也需要将其明确提及为静态的……但为什么默认情况下不强制执行? (来自comment)关键字 static 如果是公共的,则需要存在。

我没有看到这个。所有接口方法都是公共的,无论它们是否明确声明。这与静态或默认方法是正交的。

事实上,用默认值指定静态会产生错误。

是的,方法可以是静态的或默认的,但不能同时是两者。

我得到一个错误“接口抽象方法不能有主体”

如果您收到此错误,则必须将块 { ... } 指定为抽象方法的主体,无论该方法是否显式声明为抽象。

(JDK 9 最近在接口中增加了对私有方法的支持。)

【讨论】:

    【解决方案2】:

    从 1.8 开始,java 允许接口中的方法定义主体

    不,它没有。您可以 - 实际上必须 - 为标记为 defaultstatic 的方法定义一个主体。但是您不能为抽象方法定义主体,这是您尝试做的。

    方法可以是abstractdefaultstatic。如果没有使用关键字,则为abstractabstract 表示没有实现。 default 意味着有一个实现,如果一个类不提供它自己的实现。标记为 static 的方法未继承到类。

    所以它们都是不同的,有不同的用途,不能混用。应该继承一个默认方法,所以它不能是static

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      • 2012-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多