JAVA8新特性--方法引用
方法引用是什麼?
w3c教程上這樣解釋:方法引用通過方法的名字來指向一個方法。反正這句話我是看不明白啥意思,結合下面的要介紹的例子我認為這樣解釋更通俗易懂(瞭解方法引用前,建議先了解下Lambda表示式,請戳:Lambda表示式):方法引用就是一個特殊的Lambda表示式,如果某個方法和Lambda表示式的內容一樣,那麼就可以將這個Lambda替換成方法引用的形式。
方法引用的四種形式:
- 構造器引用:它的語法是Class::new,或者更一般的Class< T >::new
- 靜態方法引用:語法是Class::static_method
- 特定類的任意例項的方法引用:它的語法是Class::method
特定例項的方法引用:它的語法是instance::method
下面詳細介紹四種形式,先引入例子:
class Car {
//建立車
public static Car create(final Supplier<Car> supplier) {
return supplier.get();
}
//撞車
public static void collide(final Car car) {
System.out.println("Collided " + car.toString());
}
//跟車
public void follow(final Car another) {
System.out.println("Following the " + another.toString());
}
//修車
public void repair() {
System.out.println("Repaired " + this.toString());
}
}
- 構造器引用
final Car car = Car.create( Car::new );
我們看下使用Lambda表示式的寫法:
final Car car = Car.create( ()->new Car());
再看下在JAVA7中的寫法:
final Car car = Car.create(new Supplier<Car>() {
@Override
public Car get() {
return new Car();
}
});
這樣是不是明白了呢,工廠方法create需要一個匿名內部類作為引數,裡面的get()方法每次呼叫產生一個例項,Lambda表示式就是這個匿名內部類的簡寫形式,而構造器引用則是Lambda表示式的簡寫形式。
- 靜態方法引用
此處介紹使用了JAVA8中集合的forEach,不瞭解的請戳:JAVA8集合遍歷之forEach
//先建立一個集合
final List< Car > cars = Arrays.asList( car );
cars.forEach( Car::collide );
我們看下Lambda寫法:
cars.forEach((o)->Car.collide(o));
再看下java7中的寫法:
for (Car o : cars) {
Car.collide(o);
}
在JAVA7中遍歷cars並將其中的物件傳遞給靜態方法collide,JAVA8中的集合遍歷forEach隱含了一個car物件,所以Lambda中也是使用了一個引數,靜態方法引用所對應的方法collide也是隻有一個car物件,也就是說,靜態方法引用的使用必須保證和其引用的靜態方法的引數個數一致。
- 特定類的任意例項的方法引用
cars.forEach( Car::repair );
Lambda寫法:
cars.forEach((o)->o.repair());
JAVA7中寫法:
for (Car o : cars) {
o.repair();
}
通過JAVA7的寫法能看到特定類的任意例項的方法引用的解釋:使用的是Car類的例項o的repair方法的引用。
- 特定例項的方法引用
//建立個例項
final Car police = Car.create( Car::new );
cars.forEach( police::follow );
Lambda寫法:
cars.forEach((o)->police.follow(o));
JAVA7中寫法:
for (Car o : cars) {
police.follow(o);
}
通過JAVA7的寫法也能看到對 特定例項的方法引用的解釋:使用的是一直是Car類的police例項的方法follow。
後兩種方法引用開始實在有點難以理解,但是通過結合JAVA7中的寫法,很容易就想明白了。
總結(使用場景):
構造器引用:是對匿名內部類的使用的一種簡寫形式。
靜態方法引用:就是對靜態方法的引用簡寫形式。
特定類的任意例項的方法引用:就是使用指定類的任意一個例項的方法的簡寫形式。
特定例項的方法引用:就是使用指定類的指定例項的方法的簡寫形式。