函数式接口
函数式接口可以理解为一个抽象类,在接口里面可以定义类,定义方法体。只有在Java8里面才能在接口定义方法体,其他Java版本是不能支持的。
函数接口只能定义唯一的抽象方法(但是可以有多个非抽象方法的接口),所以函数式接口是非常脆弱的,只要开发者在该接口中多添加一个函数,那么该接口就不再是函数式接口,运行时就会报错。为了克服这种层面的脆弱性,并显式地告知某个接口是函数式接口,Java8提供了一个特殊的注解叫@FunctionalInterface,如果注解了这个注释的接口多于一个抽象方法的时候,编译就会报错。
但是静态方法是不会破坏函数式接口的。函数式接口里面可以定义静态方法,这个静态方法一定要有方法体,不然会报错。
函数式接口允许定义顶层父类Object类里面的public方法,如equals(),toString()方法。所以如果想在接口定义多个方法可以用这种方法。重写Object中的方法,不会计入接口方法中,除了final不能重写的,Object中所能重写的方法,写到接口中,不会影响函数式接口的特性。
下面给出函数式接口的例子:
package com.harry;
public class Java8Tester {
@FunctionalInterface
interface MathOperation {
int operation(int a, int b);
boolean equals(Object obj);
static void doSomething(){
System.out.print("我是一个函数式接口中的静态方法");
}
public String toString();
}
interface GreetingService {
void sayMessage(String message);
}
private int operate(int a, int b, MathOperation mathOperation){
return mathOperation.operation(a, b);
}
public static void main(String args[]){
Java8Tester tester = new Java8Tester();
// 类型声明
MathOperation addition = (int a, int b) -> a + b;
// 不用类型声明
MathOperation subtraction = (a, b) -> a - b;
// 大括号中的返回语句
MathOperation multiplication = (int a, int b) -> { return a * b; };
// 没有大括号及返回语句
MathOperation division = (int a, int b) -> a / b;
System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
System.out.println("10 / 5 = " + tester.operate(10, 5, division));
// 不用括号
GreetingService greetService1 = message ->
System.out.println("Hello " + message);
// 用括号
GreetingService greetService2 = (message) ->
System.out.println("Hello " + message);
greetService1.sayMessage("Runoob");
greetService2.sayMessage("Google");
}
}
更进一步的用法请参考https://www.jianshu.com/p/1d9b43f96e5b