Java8的新特性

weixin_30924079發表於2020-04-04

參考文章:

http://blog.csdn.net/yczz/article/details/50896975

https://www.javacodegeeks.com/2014/05/java-8-features-tutorial.html

 1、語言的新特性

  1.1、Lambda表示式

// 引數型別編譯器推理
Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );
// 引數型別顯示指定
Arrays.asList( "a", "b", "d" ).forEach( ( String e ) -> System.out.println( e ) );
// 程式碼塊
Arrays.asList( "a", "b", "d" ).forEach( e -> {
System.out.print( e );
System.out.print( e );
} );
// 返回值編譯器推理
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> e1.compareTo( e2 ) );
// 返回值顯示指定
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> {
int result = e1.compareTo( e2 );
return result;
} );
// 變數隱式轉成final
String separator = ",";
Arrays.asList( "a", "b", "d" ).forEach( ( String e ) -> System.out.print( e + separator ) );
// 變數顯示指定final
final String separator = ",";
Arrays.asList( "a", "b", "d" ).forEach( ( String e ) -> System.out.print( e + separator ) );

 1.2、函式式介面@FunctionalInterface

函式式介面指的是隻有一個函式的介面,這樣的介面可以隱式轉換為Lambda表示式。java.lang.Runnable和java.util.concurrent.Callable是函式式介面的最佳例子。
在實踐中,函式式介面非常脆弱:只要某個開發者在該介面中新增一個函式,則該介面就不再是函式式介面進而導致編譯失敗。為了克服這種程式碼層面的脆弱性,並顯式說明某個介面是函式式介面,Java 8 提供了一個特殊的註解@FunctionalInterface
函式式介面的定義:

@FunctionalInterface
public interface Functional {
    void method();
}

不過有一點需要注意,預設方法和靜態方法不會破壞函式式介面的定義,因此如下的程式碼是合法的。

@FunctionalInterface
public interface FunctionalDefaultStaticMethods {
    void method();
    default void defaultMethod() {
    }
    static void staticMethod() {
    }
}

Lambda表示式的細節,可以參考官方文件:https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

 1.3、介面預設方法和靜態方法

預設方法是使用default關鍵字定義的一個預設方法。預設方法和抽象方法之間的區別在於抽象方法需要實現,而預設方法不需要。介面提供的預設方法會被介面的實現類繼承或者覆寫,
例子程式碼如下:

private interface Defaulable {
    default String notRequired() { 
        return "Default implementation";
    }
    static String staticMethod() { 
        return "static";
    }
}

private static class DefaultableImpl implements Defaulable {
}

private static class OverridableImpl implements Defaulable {
    @Override
    public String notRequired() {
        return "Overridden implementation";
    }
}

Defaulable介面使用關鍵字default定義了一個預設方法notRequired()。DefaultableImpl類實現了這個介面,同時預設繼承了這個介面中的預設方法;OverridableImpl類也實現了這個介面,但覆寫了該介面的預設方法,並提供了一個不同的實現。
靜態方法

private interface DefaulableFactory {
    // Interfaces now allow static methods
    static Defaulable create( Supplier< Defaulable > supplier ) {
        return supplier.get();
    }
}

下面的程式碼片段整合了預設方法和靜態方法的使用場景:

public static void main( String[] args ) {
    Defaulable defaulable = DefaulableFactory.create( DefaultableImpl::new );
    System.out.println( defaulable.notRequired() );

    defaulable = DefaulableFactory.create( OverridableImpl::new );
    System.out.println( defaulable.notRequired() );
}

這段程式碼的輸出結果如下:
Default implementation
Overridden implementation

 由於JVM上的預設方法的實現在位元組碼層面提供了支援,因此效率非常高。預設方法允許在不打破現有繼承體系的基礎上改進介面。該特性在官方庫中的應用是:給java.util.Collection介面新增新方法,如stream()、parallelStream()、forEach()和removeIf()等等。儘管預設方法有這麼多好處,但在實際開發中應該謹慎使用:在複雜的繼承體系中,預設方法可能引起歧義和編譯錯誤。

如果你想了解更多細節,可以參考官方文件:https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

 

轉載於:https://www.cnblogs.com/yangchongxing/p/8359319.html

相關文章