1. 程式人生 > >JDK1.5、1.7、1.8新特性

JDK1.5、1.7、1.8新特性

JDK1.5
靜態匯入
1. import:表示去找哪一個類/去哪一個包下找哪些被使用到的類。
在Java語言中,java.lang包下的API,不需要匯入,直接可以使用。
匯入包的語法: import 被引入類的全限定名;
import 包 . *
2. 靜態匯入 : 如果我們需要使用某一個類中的靜態成員(欄位/方法/內部類),此時可以使用靜態匯入。
import static 被引入類的全限定名 . 靜態的成員;
import static 被引入類的全限定名 . *;
3. 靜態引入,屬於語法糖,僅僅是為了方便程式設計師操作簡單。但是在開發中,不推薦使用靜態引用,因為都不知道靜態成員到底來源於哪一個類。

可變引數
1. 為了解決同一種類型的引數個數不確定的問題,可以使用可變引數。
2. 方法的可變引數,其本質是陣列。
如:getTotalPrice(CartItem … items){ … };
編譯之後:
getTotalPrice(CartItem[ ] items){ … };
3. 方法的可變引數也是一個語法糖。
4. 可變引數必須作為方法的最後一個引數而存在,避免參數的歧義。

for-each
1. 增強for迴圈:可以迭代陣列和集合,取出其中的元素。
2. 語法:
for(元素型別 變數:陣列/iterable物件){
//TODO
}
3. For-each
針對於陣列來說,底層依然使用的for迴圈迭代陣列,使用陣列的索引來獲取每一個元素。
針對於Iterable物件來說:底層依然使用迭代器Iterator。
4. For-each也是Java5提供的語法糖。
5. For-each和Iterator的選擇:
如果僅僅只是迭代出集合中的元素,最簡單的方式:for-each
如果在迭代集合元素的時候,需要做刪除的操作,只能使用Iterator的remove方法來做刪除。

自動裝箱和拆箱
1. 裝箱:把基本資料型別包裝成對應的包裝類型別。Int–>Integer
拆箱:把包裝類物件轉換為對應的基本型別的變數。Iteger–>int
2. 在Java5之前,只能手動完成裝箱/拆箱:
Integer num1 = Integer.valueOf(123);
Int num2 = num1.intValue();
從Java5開始,支援自動裝箱和拆箱。可以直接把基本型別值賦給對應的包裝類物件/把包裝類物件直接賦給對應的基本型別變數。
3. 自動裝箱和拆箱也是語法糖。
4. 擴充套件:(不是JDK1.5的新特性)
在包裝類中有一個享元設計(快取):把常用的數存到常量池中。每次使用的時候從常量池去獲取,沒必要重新建立。(提高效率)
Byte、Short、Integer、Long在[-128,127],共享同一個物件
Character:在[0,127]之間共享同一個物件。

泛型(Generic Type)
1. 為什麼需要泛型:
① 保證集合中元素的安全。(TreeSet儲存的元素,必須是同一種資料型別的)
② 避免強制型別轉換。
2. 語法:
Set set = new TreeSet( );
Java7支援菱形語法:Set set = new TreeSet<>( );
3. 泛型的擦除:在編譯之後,泛型就消失了。所以泛型也是一種語法糖。
注意:泛型沒有繼承的概念:List list = new List;// 錯誤的
4. 堆汙染:在Java中,當一個可變泛型引數指向一個無泛型引數時,堆汙染就有可能發生。
① 使用泛型
② 使用可變引數
堆汙染有可能導致更嚴重的後果:ClassCastException

列舉
1. 列舉:是一種特殊的類,用於表示多種固定的狀態。
2. 語法:
public enum 名字{
物件1,物件2;
}
3. 列舉類底層繼承了java.lang.Enum類。
4. 列舉類的特點:
① 列舉類很安全,不能被例項化物件,甚至使用反射也不能建立物件。
② 可以使用name()和oridnal()方法用於返回列舉物件的例項名稱和序數(從0開始)
③ 所有的列舉類都有靜態方法values(),可以獲取當前列舉類中所有的例項。
④ 所有的列舉都有靜態方法valueOf(),可以把String型別的字串,轉換為列舉型別的物件。
⑤ 列舉常量必須最先宣告,並且常量之間用逗號隔開,最後一個常量後是分號。
⑥ 列舉類常量之後若使用 { },則表示當前列舉類的匿名內部類。
5. switch(語句){ }:
switch支援的型別:byte、short、int、char(switch支援int型別)。
因為Java5開始有自動拆箱,所以也支援Byte,Short,Character,Integer。
switch也支援列舉型別:列舉物件的ordinal方法返回的就是int型別的序數。

註解
1. JDK1.5,Java開始對元資料的支援,也就是Annotation。
2. 所有的Annotation都是java.lang.annotation.Annotation介面的子介面,所以說註解是一種特殊的介面。
3. JDK自帶的註解
@Override 限定覆寫父類的方法
@Deprecated 標記已過時,不推薦使用。在JDK1.5之前,使用文件註釋來標記過時。
@SuppressWarnings 抑制編譯器發出的警告
@SuppressWarnigns(value=“all”)
@SafeVarags 抑制堆汙染警告(JDK1.7開始出現的),該註解僅僅是抑制住編譯器不要報警告,但是存在的風險依然存在。

JDK1.7

  1. switch可以接受String型別。
    switch支援的是int型別。
    ① byte、short、char可以自動提升為int型別;以及他們對應的包裝類(JDK1.5有了自動裝箱和拆箱)
    ② 列舉(ordinal方法返回的是int型別的序數)
    ③ Sting(hashCode方法,返回的是int型別)
  2. 二進位制數字表達式
    ①增加了二進位制字面量的表示
    ②在數字中可以新增"_"分隔符
  3. 菱形語法:使用泛型的時候增加了型別推斷機制。
  4. 自動資源關閉:增加了 try-with-resources語句,可以確保在該語句執行完畢之後關閉每個資源.不需要顯示呼叫close()方法
    例:
    try( InputStream fis = new FileInputStream(“input.txt”); ){
    while(fis.read() != null){
    syso(fis.read);
    }
    }catch(Exception e){
    e.printStackTrace();
    }
  5. 捕獲組:同時捕獲多個異常處理。異常之間使用 |
  6. Objects類(提供了一下方法來操作物件,這些工具方法大多是空指標安全的);
    ThreadLocalRandom類(隨機數生成器,解決了Random類在多執行緒下多個執行緒競爭內部唯一的原子性種子變數,而導致大量執行緒自旋重試的不足。)。
  7. 堆汙染和@SafeVarargs,抑制堆汙染警告的標籤。
  8. 增加了fork/join框架用來增強對處理多核平行計算的支援.
    fork把一個大任務切分為若干個小任務,join把合併這些子任務的執行結果.

JDK1.8

  1. 增加了對Lambda表示式的支援
    基本語法: (parameters) -> expression 或 (parameters) -> {statements;}
    例: ArrayList(1, 7, 2) . forEach(i -> System.out.println(i)); // i的型別由編譯器推測出來

    Java8之前使用匿名函式的方法來代替Lambda表示式,如:
    Arrays.sort(people,new Comaparator(){
    @Override
    public int compare(Person a,Person b){
    Return a.getAge() - b.getAge();
    }
    });
    採用Lambda表示式之後:
    Arrays.sort(people,(Person a,Person b) -> a.getAge() - b.getAge());

    Arryas.sort(people,(a,b) -> a.getAge() - b.getAge());

  2. 介面增加了方法的預設實現和靜態方法.通過使用default關鍵字可以給介面中的方法新增預設實現.
    Interface Inter8{
    void f();
    default void g(){
    syso(“this is default method in interface”);
    }
    static void h(){
    syso(“this is static method in interface”);
    }
    }

  3. 方法引用:指的是可以直接引用Java類或物件的方法,可以被看成是一種更加簡潔易懂的Lambda表示式.
    使用方法引用後,上述排序程式碼變為:
    Arrays.sort(people,Comparator.comparing(Person::getAge));

    方法引用有4種方式:
    ①引用構造方法: ClassName::new
    ②引用類靜態方法: ClassName::methodName
    ③引用特定類的任意物件方法: ClassName::methodName
    ④引用某個物件的方法: instanceName::methodName

  4. 註解(Annotation)
    JDK1.5中引入了註解機制,但是有一個限制:相同的註解在同一位置只能宣告一次.
    JDK1.8引入了重複註解機制,相同的註解在同一個地方可以宣告多次.
    備註:java內建了三種註解方式:
    @Override – 表示當前方法時覆蓋父類的方法
    @Deprecated – 表示當前元素是不贊成使用的
    @SuppressWarnings – 表示關閉一些不當的編譯器警告資訊
    注意:它們都定義在java.lang包中

  5. 型別推測
    例:
    class List{
    static List test01(){ … };
    static List test02(Z head,List tail){ … };
    E head(){ … }
    }
    List list = List.test01();
    List.test02(5,List.test01()); // 通過方法的第一個引數來推測泛型的引數

  6. 引數名字
    JDK1.8通過在變異的時候增加 -parameters選項,以及增加反射API與Parameters.getName()方法實現了獲取方法引數名的功能

  7. 新增Optional類
    JDK1.8引入了Optional類來處理空指標的情況,從而增強程式碼的可讀性.

  8. 新增了Stream類
    stream是流水線操作,內部迭代,對集合的操作更簡單

  9. 日期新特性
    JDK1.8之前,處理日期相關的類主要有如下三個:
    ①Calendar:實現日期和時間欄位之間轉換,它的屬性是可變的,執行緒不安全
    ②DataFormat:格式化和分析日期字串
    ③Date:用來承載日期和時間資訊,屬性可變,執行緒不安全
    JDK1.8新增了API,java.time主要包含了處理日期、時間、日期/時間、時區、時刻和時鐘等操作

  10. 增加了呼叫JavaScript的引擎.
    JDK1.8增加API使得可以通過java程式來呼叫JavaScript程式碼
    javax.script.ScriptEngineManager

  11. Base64.
    Base64編碼是一種常見的字元編碼,可用來作為電子郵件或web service附件的傳輸編碼.

  12. 並行陣列 – JDK1.8增加了對陣列的並行處理的方法(parallerXxx)