Java8新增静态方法及默认方法

静态与私有方法

目前为止,通常的做法都是将静态方法放在接口伴随类中。如:Collection/Collections、Path/Paths。

在java8中,允许在接口中增加静态方法。那么,如果我们自己现在来定义一个接口类,就可以在接口中定义一些常用的静态方法,而不用在去写一个接口伴随类了。

在java9中,接口中的方法可以是private。private方法可以是静态方法或实例方法。

默认方法

接口中可以提供一个默认实现方法,但必须要用default修饰符标记。默认实现的方法,在类中可以不去实现。而且,在默认实现中,可以调用其他方法。

interface I1
{
    String name = "JAVA";

    int size();

    default boolean isEmpty()
    {
        return size() == 0;
    }
}

默认方法还有重要用法就是“接口演化”。比如,上述的I1接口在项目的1.0版本的代码如上。但在1.1中,需要向其加入一个list方法。这时候就应该给其list方法弄个默认实现,这样就不会影响到之前实现该接口的类的正常编译了。

默认方法冲突

如果先在一个接口中将一个方法定义为默认方法,然后又在另一个超类或另一个接口中定义同样的方法,会发生什么情况?

1.超类优先。如果超类提供了一个具体方法,同名而且有相同的参数类型的默认方法会被忽略。

2.接口冲突。如果一个接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否为默认参数)相同的方法,必须覆盖这个方法并解决冲突。

interface Person
{
    default String getName() {return "";}
}

interface Named
{
    default String getName () {
        return getClass().getName() + "_" + hashCode();
    }
}

class Paul implements Person,Named
{

}

以上代码将会编译失败。现在只需要在Pual类中提供一个getName方法即可。

class Paul implements Person,Named
{
    public String getName () {
        return Person.super.getName();
    }
}

现在,该代码可以成功编译了。

当然,如果两个接口都没有为共享方法提供默认实现,那么就不存在冲突。实现了可以有两个选择:实现这个方法,或者干脆不实现。