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<>()
歡迎您關注T-park技術工匠,我們是一群來自阿裡巴巴的工程師,在這裡将為您分享網際網路技術幹貨。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZaBHZtxkc1cVWzpkMYpGbHNmd0IjY0FjMipWO5lFcCNDT6ZlMahWMXFmd0IjYwJFWhtmVHJGdShUYmFzViZnTywUd5cVYww2RaxGeXJGMoJDTP5EMY9GczwkeW12Y3FjMMRXOykVdFh1Y1RzVhRDbXp1M1M0Y0lTeMZTTINGMShUYvwlbj5yZtlmbkN3YuQnclZnbvN2Ztl2Lc9CX6MHc0RHaiojIsJye.jpg)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZaBHZtxkc1cVWzpkMYpGbHNmd0IjY0FjMipWO5lFcCNDT6ZlMahWMXFmd0IjYwJFWhtmVHJGdShUYmFzViZnTywUd5cVYww2RaxGeXJGMoJDTP5EMY9GczwkeW12Y3FjMMRXOykVdFh1Y1RzVhRDbXp1M1M0Y0lTeMZTTINGMShUYvwlbj5yZtlmbkN3YuQnclZnbvN2Ztl2Lc9CX6MHc0RHaiojIsJye.jpg)