面試中經常被問到的JDK8新特性 ,你知道多少?

序言

面試官經常會問到新版JDK新的特性, 尤其是JDK8的特性。

下面將首先講解JDK版本發佈情況,概括性介紹JDK8的主要新的特徵。

主要包括:

  • 新的語言特性
  • 集合對象的修改
  • JVM新特性
  • HashMap的修改

關注“”非典型理科男“”公衆號, 回覆 jdk文檔 獲取JDK官方文檔合集。

爲什麼面試經常問JDK8新的特性

JDK8是2014年3月發行版本, 面試官會在面試中問JDK8的一些新的特性。

Java從已經從JDK1.0版本發展到了最新的JDK13, 爲什麼目前Jdk8經常被問到呢?

大概有一些原因:

第一、JDK8仍然是最受歡迎的JDK版本。

從skyn網站的《2018年JVM生態報告》中可以看到截止到2018年, JDK8仍然是生成環境使用最多的JDK版本。


第二、新的發版週期,讓很多公司無所適從。JDK9非LTS版本。

JDK8之後Oracle使用了新的發佈週期。

《javaSE support roadMap》》

從JDK版本歷史發行看, Oracle從Java9開始實行了新的版本發佈規則,縮短了新版本發佈週期。

JDK1.6到JDK1.7經過了5年的時間

JDK1.7到JDK1.8經過了3年

JDK1.8到JDK1.9經過了3年

之後的版本 每6個月發佈一個版本

每3年發佈一個LTS版本(最新的LTS版本是JDK11)

幾乎 三分之一 的開發人員還不知道他們將如何應對新的發佈週期。

第三、JDK8 引入了很多非常實用和長期的影響

  1. JDK8引入新的語法特性,比如Lambda表達式,默認方法,方法引用,新增新的日期處理類
  2. JDK8爲Collection新增Stream流式接口, 修改HashMap和ConcurrentHashMap實現
  3. JDK8修改了JVM內存模型, 實用metaSpace代替永久代
  4. JDK新增併發接口和實現, 包括新增CompletableFuture、爲ConcurrentHashMap新增支持Stream方法、新增StampedLock

下面介紹幾個面試過程經常被問到的幾個新特性

Lambda表達式、方法引用和默認方法

1. Lambda表達式

Lambda表達式允許把函數作爲一個方法的參數。

有幾種常見的Lambda表達式:

// 1. 不需要參數,返回值爲 5  
() -> 5  
  
// 2. 接收一個參數(數字類型),返回其2倍的值  
x -> 2 * x  
  
// 3. 接受2個參數(數字),並返回他們的差值  
(x, y) -> x – y  
  
// 4. 接收2個int型整數,返回他們的和  
(int x, int y) -> x + y  
  
// 5. 接受一個 string 對象,並在控制檯打印,不返回任何值(看起來像是返回void)  
(String s) -> System.out.print(s)

2. 方法引用

JDK8支持了四種方式方法引用

類型 方法引用
引用靜態方法 ContainingClass::staticMethodName
引用特定對象的實例方法 containingObject::instanceMethodName
引用特定類型的任意對象的實例方法 String::compareToIngoreCase
引用構造函數 ClassName::new

3. 默認方法和靜態方法

JDK1.8支持在接口中定義默認方法和靜態方法, 默認方法可以被接口實現引用。

package defaultmethods;
 
import java.time.*;

public interface TimeClient {
    void setTime(int hour, int minute, int second);
    void setDate(int day, int month, int year);
    void setDateAndTime(int day, int month, int year,
                               int hour, int minute, int second);
    LocalDateTime getLocalDateTime();
    
    // 靜態方法
    static ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }
    
    // 默認方法
    default ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }
}

Colletion的修改

JDK1.8增強了Collection FrameWork, 支持了lambda, 流和聚合操作。

改動有兩個方面:

  • 支持了lambda, 流和聚合操作
  • 改進的類型推斷

改進的類型推斷

Java編譯器利用目標類型來推斷通用方法調用的類型參數。

考慮以下示例:

List <String> stringList = new ArrayList <>();
stringList.add("A");
stringList.addAll(Arrays.asList());

Java管理擴展(JMX)提供了對診斷命令的遠程訪問。

目前,不考慮泛型,該方法addAll將Collection實例作爲其參數,然後該方法Arrays.asList返回一個List實例。這是有效的,因爲List是的子類型Collection。

現在考慮泛型,的目標類型addAll爲Collection<? extends String>,並Arrays.asList返回一個List實例。在此示例中,Java SE 8編譯器可以推斷類型變量的T值爲String。編譯器從目標類型推斷出這一點Collection<? extends String>。

Java SE 7和更早版本的編譯器不接受此代碼,因爲它們不使用目標類型來推斷方法調用參數的類型。例如,Java SE 7編譯器生成類似於以下內容的錯誤消息:

error: no suitable method found for addAll(List<Object>) ...
method List.addAll(Collection<? extends String>) is not applicable (actual argument List<Object> cannot be converted to Collection<? extends String> by method invocation conversion)

因此,在Java編譯器無法推斷類型的情況下,必須使用顯式指定類型變量的值。例如,以下在Java SE 7中有效:

List <String> stringList = new ArrayList <>();
stringList.add(“ A”);
stringList.addAll(Arrays.<String> asList());

JVM新特性

JDK8在JVM中修改重要有:

  • 新增JVM工具:jdeps提供了用於分析類文件的命令行工具。
  • 使用metaSpace代替永久區
  • 新增NMT(Native Memeory Trace)本地內存跟蹤器,參見NMT

HashMap變化

JDK8優化了HashMap的實現, 主要優化點包括:

  • 將鏈表方式修改成鏈表或者紅黑樹的形式
  • 修改resize的過程,解決JDK7在resize在併發場景下死鎖的隱患
  • JDK1.7存儲使用Entry數組, JDK8使用Node或者TreeNode數組存儲

當鏈表長度大於8是鏈表的存儲結構會被修改成紅黑樹的形式。

查詢效率從O(N)提升到O(logN)。鏈表長度小於6時,紅黑樹的方式退化成鏈表。

JDK7鏈表插入是從鏈表頭部插入, 在resize的時候會將原來的鏈表逆序。

JDK8插入從鏈表尾部插入, 因此在resize的時候仍然保持原來的順序。

👁 關注微信公衆號:非典型理科男 回覆:JDK文檔 獲取JDK官方文檔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章