函數式接口
函數式接口可以理解爲一個抽象類,在接口裏面可以定義類,定義方法體。只有在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