[TOC]java
@FunctionalInterface
注解,那么编译器就会按照函数式接口的定义来要求该接口函数式接口应知足:jvm
- 该接口是一个接口类型而不是注解类型,枚举类型或类类型
- 被声明
@FunctionalInterface
注解的接口应该知足函数式接口的定义若是不知足上述条件,编译器就会生成错误信息。ide
@FunctionalInterface
注解,那么编译器依旧会将该接口看做是函数式接口 若是一个接口声明了抽象方法,但该抽象方法重写了 Object 类里的一个公有方法,那么对于 Java 编译器来讲,它并不会认为该方法符合函数式接口的抽象方法(即不把该方法看成函数式接口的抽象方法)。由于接口的实现类都会直接或间接继承 Object 这个根类,因此在函数式接口中定义与 Object 类中签名同样的方法是不会致使函数式接口失效的。函数
举例:ui
举例的接口声明为函数式接口,并重写了 toString()
这个 Object()
方法,可是并不会报错:this
@FunctionalInterface public interface MyInterface { void test(); String toString(); }
jdk1.8 之后接口里面能够定义方法的实现,这种方法叫作 default-method。spa
举例:code
举个例子:forEach方法继承
default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
该实现方法定义在 Iterable 中。接口
jdk1.8 后接口也能够定义静态方法。
举例:
public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() { return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE; }
若是接口声明了 default 方法,而且某类实现了该接口,那么 default 方法将会被继承。
这里有个问题:
若是有一个类继承了两个不一样接口的同名 default 方法,jvm 编译器是没法识别到底该使用哪一个方法的,必须重写 default 方法,以下:
public class MyClass implements MyInterface1, MyInterface2 { @Override public void myMythod() { MyInterface2.super.myMethod(); } public static void main(String[] args) { MyClass myClass = new MyClass(); myClass.myMethod(); } }
能够重写也能够在重写方法中指定要继承接口的 default 方法。
实现类的优先级比接口高。
public class MyClass extends MyInterfaceImpl implements MyInterface2 { public stativ void main(String[] args) { MyClass myClass = new MyClass(); myClass.myMethod(); } }
MyInterfaceImpl 中有个和 MyInterface2 同名的 myMethod()
方法。
运行上述代码,编译器并不会报错,由于实现类的优先级比接口高,因此 myClass.myMethod()
调用的方法默认是 MyInterfaceImpl 类中的实现方法。