-2

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

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

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

编辑:看到反对票的数量,我鼓励你先尝试一下,然后再难以置信地得出结论

4

2 回答 2

2

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

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 ) 最后,声明的方法default必须static有一个块{ ... }作为主体,而抽象方法(无论是否声明)必须有一个分号;作为主体。( JLS 9.4.3 )

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

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

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

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

我收到错误“接口抽象方法不能有正文”

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

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

于 2015-04-02T00:39:59.227 回答
0

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

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

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

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

于 2015-04-02T08:24:02.977 回答