接口中的静态公共方法和非静态默认方法

时间:2015-04-01 19:05:46

标签: java java-8 default-method

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

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

从1.8开始,java允许接口中的方法定义主体。然而,有一些语义特点;如果方法是公共的,我需要明确地将其称为静态,这是可以理解的,但为什么这不是默认强制执行的?事实上,使用default指定static会产生错误。这有什么用途?

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

2 个答案:

答案 0 :(得分: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,界面中的方法都是公开的。另外,方法可以是abstract,default或static,如果没有指定方法,则方法是抽象的。 (JLS 9.4)最后,声明defaultstatic的方法必须为正文具有块{ ... },而抽象方法(无论是否声明)必须有分号{{ 1}}作为身体。 (JLS 9.4.3

  

如果方法是公开的,我需要明确地将其称为静态...但为什么这不会在默认情况下强制执行? (来自comment)关键字static必须存在,如果它是公开的。

我不明白这一点。所有接口方法都是公共的,无论它们是否明确声明。这与静态或默认方法正交。

  

实际上使用default指定static会产生错误。

是的,方法可以是静态的,也可以是默认的,但不能同时使用。

  

我收到错误&#34;界面抽象方法不能有body&#34;

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

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

答案 1 :(得分:0)

  

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

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

方法可以是abstractdefaultstatic。如果没有使用关键字,那么它就是abstractabstract表示没有实施。 default表示如果某个类没有提供自己的实现,则使用该实现。标记为static的方法未继承到类。

所以他们都是不同的,服务于不同的目的,不能混合。应该继承默认方法,因此它不能是static