方法引用使得開發者能夠直接引用現存的方法、Java類的構造方法或者實例對象。方法引用和Lambda表達式配合使用,使得java類的構造方法看起來緊湊而簡潔,沒有不少複雜的模板代碼。html
方法引用包括幾種狀況:java
例子中,Car類是不一樣方法引用的例子,能夠幫助讀者區分四種類型的方法引用。oracle
package com.study.demo.TestRefernce; import java.util.Arrays; import java.util.List; import java.util.function.Supplier; public class Car { private String name ="I am a car"; @Override public String toString() { return "Car{" + "name='" + name + '\'' + '}'; } public static Car create(final Supplier< Car > supplier ) { return supplier.get(); } public static void collide( Car car ) { System.out.println( "Collided " + car.toString() ); } public void follow( Car another ) { System.out.println( "Following the " + another.toString() ); } public void repair() { System.out.println( "Repaired " + this.toString() ); } public static void main(String[] args) { final Car car = Car.create(Car::new); final List< Car > cars = Arrays.asList( car ,Car.create(Car::new)); cars.forEach(Car::collide ); cars.forEach(Car::repair); final Car car1 = Car.create(Car::new); cars.forEach(car1::follow); } }
final Car car = Car.create( Car::new ); final List< Car > cars = Arrays.asList( car );
cars.forEach( Car::collide );
cars.forEach( Car::repair );
也能夠這樣:框架
cars.forEach(c -> c.repair());
final Car police = Car.create(Car::new); cars.forEach((car1) -> police.follow(car1));
final Car police = Car.create( Car::new ); cars.forEach( police::follow );
運行上述例子,能夠在控制檯看到以下輸出(Car實例可能不一樣):ide
自從Java 5中引入註解以來,這個特性開始變得很是流行,並在各個框架和項目中被普遍使用。不過,註解有一個很大的限制是:在同一個地方不能屢次使用同一個註解。Java 8打破了這個限制,引入了重複註解的概念,容許在同一個地方屢次使用同一個註解。函數
在Java 8中使用@Repeatable註解定義重複註解,實際上,這並非語言層面的改進,而是編譯器作的一個trick,底層的技術仍然相同。能夠利用下面的代碼說明。學習
import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class RepeatingAnnotations { @Target( ElementType.TYPE ) @Retention( RetentionPolicy.RUNTIME ) public @interface Filters { Filter[] value(); } @Target( ElementType.TYPE ) @Retention( RetentionPolicy.RUNTIME ) @Repeatable( Filters.class ) public @interface Filter { String value(); }; @Filter( "filter1" ) @Filter( "filter2" ) public interface Filterable { } public static void main(String[] args) { for( Filter filter: Filterable.class.getAnnotationsByType( Filter.class ) ) { System.out.println( filter.value() ); } } }
正如咱們所見,這裏的Filter類使用@Repeatable(Filters.class)註解修飾,而Filters是存放Filter註解的容器,編譯器儘可能對開發者屏蔽這些細節。這樣,Filterable接口能夠用兩個Filter註解註釋(這裏並無提到任何關於Filters的信息)。this
另外,反射API提供了一個新的方法:getAnnotationsByType(),能夠返回某個類型的重複註解,例如Filterable.class.getAnnoation(Filters.class)
將返回兩個Filter實例,輸出到控制檯的內容以下所示:spa
filter1 filter2
若是你但願瞭解更多內容,能夠參考官方文檔。code
Java 8編譯器在類型推斷方面有很大的提高,在不少場景下編譯器能夠推導出某個參數的數據類型,從而使得代碼更爲簡潔。例子代碼以下:
public class Value< T > { public static< T > T defaultValue() { return null; } public T getOrDefault( T value, T defaultValue ) { return ( value != null ) ? value : defaultValue; } }
下列代碼是Value<String>類型的應用:
public class TypeInference { public static void main(String[] args) { final Value< String > value = new Value<>(); value.getOrDefault( "22", Value.defaultValue() ); } }
參數Value.defaultValue()的類型由編譯器推導得出,不須要顯式指明。在Java 7中這段代碼會有編譯錯誤,除非使用Value.<String>defaultValue()
。
Java 8新增的兩個註解:
Java 8拓寬了註解的應用場景。如今,註解幾乎可使用在任何元素上:局部變量、接口類型、超類和接口實現類,甚至能夠用在函數的異常定義上。下面是一些例子:
package com.javacodegeeks.java8.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.ArrayList; import java.util.Collection; public class Annotations { @Retention( RetentionPolicy.RUNTIME ) @Target( { ElementType.TYPE_USE, ElementType.TYPE_PARAMETER } ) public @interface NonEmpty { } public static class Holder< @NonEmpty T > extends @NonEmpty Object { public void method() throws @NonEmpty Exception { } } @SuppressWarnings( "unused" ) public static void main(String[] args) { final Holder< String > holder = new @NonEmpty Holder< String >(); @NonEmpty Collection< @NonEmpty String > strings = new ArrayList<>(); } }