1.介面改進
以前Java的介面裡只能聲明方法和定義常量,現在可以在介面裡定義靜態方法和預設方法。
定義靜態方法
定義靜態(static)方法帶來的好處就是可以減少建立工具類的需求了。比如 java.util.Collection介面定義了一個集合,對於此介面執行個體操作的很多通用方法都是通過工具類 java.util.Collections來提供的,現在可以在介面裡定義靜態方法,我們就可以把工具類裡的靜態方法直接移到介面類裡,不需要獨立建立工具類了。
定義預設方法
另一個改進是,可以在不破壞現有介面實現的前提下添加預設(default)方法。比如java.lang.Iterable 介面現在擁有一個預設的 forEach 方法:
public default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
預設方法不能覆蓋 equals, hashCode, toString 方法
一個介面不能提供Object類裡的任何方法的預設實現。這意味著不能在介面裡提供 equals, hashCode, toString 方法的預設實現。
2.函數介面
函數介面是Java8引入的一個核心概念。如果一個介面只定義了一個抽象方法,它就是函數介面。例如java.lang.Runnable就是一個函數介面,因為它只定義了一個抽象方法: public void run()。
預設方法不是抽象的,所以一個函數介面可以定義任意多的預設方法。
新引入的註解 @FunctionalInterface 用來表明介面準備成為函數介面,但不管有沒有這個註解,編譯器都認為只有一個抽象方法的介面是函數介面。
3.Lambdas
函數介面一個極具價值的屬性是可以在lambdas裡執行個體化。下面是lambdas的一些執行個體:
(param1 ParamType1, param2 ParamTeyp2, ... ) -> { statements; } // lambdas 完整形式
(int x, int y) -> { return x + y; } // 完整輸入參數類型,具有返回語句的語句塊
(x, y) -> x + y // 自動類型推導參數類型,語句塊只有一條 return 語句時可以省略大括弧和return關鍵字,
x -> x * x // 只有一個輸入參數,可以省略入參列表的小括弧。
() -> x // 如果沒有入參,小括弧不能省略。
x -> { System.out.println(x); } // 沒有返回語句,語句塊的大括弧不能省略。
4.方法引用
靜態方法引用: String::valueOf。
非靜態方法引用: Object::toString。
建構函式引用: ArrayList::new。
捕獲方法引用: x::toString。
方法引用等價的lambda運算式:
String::valueOf x -> String.valueOf(x)
Object::toString x -> x.toString()
ArrayList::new () -> new ArrayList<>()