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();
}
}
现在,该代码可以成功编译了。
当然,如果两个接口都没有为共享方法提供默认实现,那么就不存在冲突。实现了可以有两个选择:实现这个方法,或者干脆不实现。