虽然JDK8出来蛮久了, 但是很多JDK8的新特性并不了解。 比如在JDK8的接口之中, 新增了今天的主角 default methods
要是您已经知道了这个东西, 还请轻喷!
比如下面的示例代码:
public interface Math { int add(int a, int b); default int multiply(int a, int b) { return a * b; } }
注意上面 Math
之中的 default int multiply
。在这个方法之中, 已经有了一个默认的实现
起因是JDK8之中引入了Lambda表达式。 在很多接口之中, 需要新增一些方法。 但是, 如果这些通用接口里面新增方法, 所以实现了这个接口的类都会直接编译出错,可以说说完全没有向前兼容的特性了。
参考下面的Sample:
interface Person { //adds a java 8 default method default void sayHello() { System.out.println("Hello there!"); } } class Sam implements Person { } public class Main { public static void main(String [] args) { Samsam = new Sam(); //calling sayHello method calls the method //defined in interface sam.sayHello(); } }
最终输出:
Hellothere!
PS:这种default methods 在编程方法上, 也可以称为”防御性编程”
前面提到lambda要增加 forEach()
方法,看看实际例子:
@FunctionalInterface public interface Iterable<T> { Iterator<T> iterator(); default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } }
参考自: https://zeroturnaround.com/rebellabs/java-8-explained-default-methods/
如果多个接口有相同的default method, 在 JDK8之中会编译报错!
参考下面的例子:
interface Person { default void sayHello() { System.out.println("Hello"); } } interface Male { default void sayHello() { System.out.println("Hi"); } } class Samimplements Person, Male { //override the sayHello to resolve ambiguity void sayHello() { } }
在两个不同的接口之中,都实现了相同的default method : sayHello()
在编译的时候, 会直接报错!
如果需要使用的话, 需要明确的指定是哪个接口的 sayHello()
,如下所示:
Male.super.sayHello();
本质上,接口还是接口,并没有改变,因为接口还是不能:
其他的不细说了, 就想起这三点。
本文翻译之: http://viralpatel.net/blogs/java-8-default-methods-tutorial/
根据自己的理解做了修正与补充。
另外, 除了这个default method, 接口还支持静态方法(不确定是不是jdk8才支持的)。
可以参考下面的帖子: http://blog.csdn.net/aitangyong/article/details/54134385
本文翻译为独立翻译, 转载请注明出处:
http://www.flyml.net/2017/02/10/jdk8-new-feature-default-method