JDK 12又來了,我學不動了...讓我們先看看JDK12之前的舊特性!

原文鏈接:JDK1.5,1.6,1.7,1.8,1.9,1.10,1.11的新特性整理

【1】回顧jdk1.0-1.4

① jdk1.0

初代版本,偉大的一個里程碑,但是是純解釋運行,使用外掛JIT,性能比較差,運行速度慢。

② jdk1.1

主要特性有:

  • JDBC(Java DataBase Connectivity);
  • 支持內部類;
  • RMI(Remote Method Invocation) ;
  • 反射;
  • Java Bean;

反射參考博文:一文讀懂反射那些事


③ jdk1.2

主要特性有:

  • 集合框架;
  • JIT(Just In Time)編譯器;
  • 對打包的Java文件進行數字簽名;
  • JFC(Java Foundation Classes), 包括Swing 1.0, 拖放和Java2D類庫;
  • Java插件;
  • JDBC中引入可滾動結果集,BLOB,CLOB,批量更新和用戶自定義類型;
  • Applet中添加聲音支持.

集合使用與原理參考博文:集合與數據結構


④ jdk1.3

主要特性有:

  • Java Sound API;
  • jar文件索引;
  • 對Java的各個方面都做了大量優化和增強;

⑤ jdk1.4

主要特性有:

  • XML處理;
  • Java打印服務;
  • Logging API;
  • Java Web Start;
  • JDBC 3.0 API;
  • 斷言;
  • Preferences API;
  • 鏈式異常處理;
  • 支持IPV6;
  • 支持正則表達式;
  • 引入Imgae I/O API.

正則表達式詳解參考博文:正則表達式基礎語法與Java、JS使用實例


【2】JDK1.5

主要有:

  • 泛型(Generics)
  • 增強for循環
  • 自動拆裝箱(Autoboxing/unboxing)
  • 類型安全的枚舉(Typesafeenums)
  • 靜態導入(Static import)
  • 元數據(Metadata)
  • 線程池
  • Java Generics

① 泛型

泛型是JDK1.5中一個最“酷”的特徵。通過引入泛型,我們將獲得編譯時類型的安全和運行時更小地拋出 ClassCastExceptions的可能。在JDK1.5中,你可以聲明一個集合將要接收/返回的對象的類型。在JDK1.4中,創建僱員名字的清單 (List)需要一個集合對象,像下面的語句:

List listOfEmployeeName = new ArrayList(); 

在JDK1.5中,你將使用下面語句

List<String> listOfEmployeeName = new ArrayList<String>(); 

如果你試圖插入非string類型的值,你將在編譯時發現並且修正這類問題。沒有泛型,很可能你所編寫的程序拋出ClassCastException異常而崩潰。

JDK1.5中Collection類庫的大部分類都被改進爲Generic類。需要注意的是類型值信息只爲Java編譯器在編譯時所用,確保代碼無類型安全問題;驗證通過之後,即被去除(泛型擦除)。對於JVM而言,只有如JDK1.5之前版本一樣的 List,並無List<Integer>和List<String>之分。這也就是Java Generics實現中關鍵技術Erasure的基本思想。以下代碼在控制檯輸出的就是“true”。

List<String> strList = new ArrayList<String>(); 

List<Integer> intList = new ArrayList<Integer>(); 

System.out.println(strList.getClass() == intList.getClass()); 

可以將Generic理解爲:爲提高Java代碼類型安全性(在編譯時確保,而非等到運行時才暴露),Java代碼與Java編譯器之間新增的一種約定規 範。Java編譯器在編譯結果*.class文件中供JVM讀取的部分裏沒有保留Generic的任何信息,JVM看不到Generic的存在。

對於Generic類(設爲GenericClass)的類型參數(設爲T):

  • 由於對於JVM而言,只有一個GenericClass類,所以GenericClass類的靜態字段和靜態方法的定義中不能使用T。T只能出現在 GenericClass的非靜態字段或非靜態方法中。也即T是與GenericClass的實例相關的信息。

  • T只在編譯時被編譯器理解,因此也就不能與運行時被JVM理解並執行其代表的操作的操作符(如instanceof 和new)聯用。

    class GenericClass {

      T t1; 
    
      public void method1(T t){ 
    
         t1 = new T(); //編譯錯誤,T不能與new聯用 
    
         if (t1 instanceof T) {}; //編譯錯誤,T不能與instanceof聯用 
    
      }; 
    
      static T t2; //編譯錯誤,靜態字段不能使用T 
    
      public static void method2(T t){};//編譯錯誤,靜態方法不能使用T 
    

    }

Generic類可以有多個類型參數,且類型參數命名一般爲大寫單字符。例如Collection類庫中的Map聲明爲:

public interface Map<K,V> { 
  //...
} 

Generic類和原(Raw)類

對每一個Generic類,用戶在使用時可以不指定類型參數。例如,對於List<E>,用戶可以以“List<String> list;”方式使用,也可以以“List list;”方式使用。“List<String>”被稱爲參數化的Generic類(類型參數被賦值),而“List”稱爲原類。原類 List的使用方式和效果與JDK1.5之前版本List的一樣,使用原類也就失去了Generic帶來的可讀性和健壯性的增強。

允許原類使用方式的存在顯然是爲了代碼的向前兼容:即JDK1.5之前的代碼在JDK1.5下仍然編譯通過且正常運行。

當你在JDK1.5中使用原類並向原類實例中添加對象時,編譯器會產生警告,因爲它無法保證待添加對象類型的正確性。編譯通過是爲了保證代碼向前兼容,產生警告是提醒潛在的風險。

泛型的使用參考博文:泛型系列講解


② 增強for循環

在JDK1.5之前版本下的For循環語法如下:

void printAll(Collection c) { 
	//這裏採用迭代器形式
      for (Iterator i = c.iterator(); i.hasNext(); ) { 
          Employee emp = (Employee)i.next(); 
          System.out.println(emp.getName()); 
      } 
  }

現在,用增強的For語句實現相同方法:

void printAll(Collection c) { 
  for (Object o : c) 
  System.out.println((TimerTask)o).getName()); 
} 

③ 自動拆裝箱(Autoboxing/unboxing)

Java有基本數據類型,在這些基本數據類型周圍又有包裝類。通常,編程人員需要將一種類型轉換成另一種。

jdk1.5以前:

public class Employee {
  private static final Integer CHILD = new Integer(0);
  public static void main(String args[]) {
      //code for adding n to an Integer
      int n = 10;
      Integer age = new Integer(30);
      Integer ageAfterTenYear = new Integer(age.intValue +10);
  }
} 

jdk1.5後使用自動拆裝箱:

public class Employee {
  public static void main(String args[]) {
      int n =10;
      Integer age = new Integer(30);
      Integer ageAfterTenYear = age +10;
  }
} 

④ 類型安全的枚舉(Type safe enums)

類型安全枚舉提供下列特性:

  • 提供編譯時類型安全。
  • 都是對象,因此你不需要將他們放入集合中。
  • 作爲一種類的實現,因此你可以添加一些方法。
  • 爲枚舉類型提供了合適的命名空間。
  • 打印的值具有情報性(informative)― 如果你打印一個整數枚舉(intenum),你只是看見一個數字,它可能並不具有情報性。

實例一:

enum Season { winter, spring, summer, fall } 

實例二:

public enum Coin { 
  penny(1), nickel(5), dime(10), quarter(25); 
  Coin(int value) { this.value = value; } 
  //設置屬性
  private final int value; 
  //設置方法
  public int value() { return value; } 
} 

參考博文:枚舉類的詳解與實例


⑤ 靜態導入(Static import)

靜態導入使代碼更易讀。通常,你要使用定義在另一個類中的常量(constants),像這樣:

import org.yyy.pkg.Increment;
class Employee {
    public Double calculateSalary(Double salary{
      return salary + Increment.INCREMENT * salary;
  }
} 

當時使用靜態導入,我們無需爲常量名前綴類名就能使用這些常量,像這樣:

import static org.yyy.pkg.Increment; 
class Employee { 
    public Double calculateSalary(Double salary{ 
      return salary + INCREMENT * salary; 
  } 
} 

注意,我們可以調用INCREMENT這一常量而不要使用類名Increment.。


⑥ 元數據(Metadata)

元數據特徵志於使開發者們藉助廠商提供的工具可以進行更簡易的開發。實例如下(Remote是用於遠程服務調用的接口):

import org.yyy.hr; 
public interface EmployeeI extends Java.rmi.Remote { 
  public String getName() throws Java.rmi.RemoteException; 
  public String getLocation () throws Java.rmi.RemoteException; 
} 
public class EmployeeImpl implements EmployeeI { 
  public String getName() { 
  } 
  public String getLocation () { 
  } 
} 

通過元數據的支持,你可以改寫實例代碼爲:

import org.yyy.hr; 
public class Employee { 
  @Remote public String getName() { 
  ... 
  } 
  @Remote public public String getLocation() { 
  ... 
  } 
} 

⑦ 線程池

Java5中,對Java線程的類庫做了大量的擴展,其中線程池就是Java5的新特徵之一,除了線程池之外,還有很多多線程相關的內容,爲多線程的編程帶來了極大便利。爲了編寫高效穩定可靠的多線程程序,線程部分的新增內容顯得尤爲重要。

線程池的基本思想還是一種對象池的思想,開闢一塊內存空間,裏面存放了衆多(未死亡)的線程,池中線程執行調度由池管理器來處理。當有線程任務時,從池中取一個,執行完成後線程對象歸池,這樣可以避免反覆創建線程對象所帶來的性能開銷,節省了系統的資源。

多線程和線程池的系列博文參考:多線程併發和線程池


【3】JDK1.6

主要特性有:

  • Desktop類和SystemTray類
  • 使用JAXB2來實現對象與XML之間的映射
  • StAX
  • 使用Compiler API
  • 輕量級Http Server API
  • 插入式註解處理API(Pluggable Annotation Processing API)
  • 用Console開發控制檯程序
  • 對腳本語言的支持
  • Common Annotations

① Desktop類和SystemTray類

在JDK1.6中,AWT新增加了兩個類:Desktop和SystemTray。

前者可以用來打開系統默認瀏覽器瀏覽指定的URL,打開系統默認郵件客戶端給指定的郵箱發郵件,用默認應用程序打開或編輯文件(比如,用記事本打開以txt爲後綴名的文件),用系統默認的打印機打印文檔。

Desktop內部有一個靜態枚舉類,其實例對象代表不同動作:

public static enum Action {
        OPEN,
       
        EDIT,
      
        PRINT,
     
        MAIL,
      
        BROWSE
    };

後者可以用來在系統托盤區創建一個托盤程序。


② 使用JAXB2來實現對象與XML之間的映射

JAXB是Java Architecture for XML Binding的縮寫,可以將一個Java對象轉變成爲XML格式,反之亦然。

我們把對象與關係數據庫之間的映射稱爲ORM,其實也可以把對象與XML之間的映射稱爲OXM(Object XML Mapping)。原來JAXB是Java EE的一部分,在JDK1.6中,SUN將其放到了Java SE中,這也是SUN的一貫做法。JDK1.6中自帶的這個JAXB版本是2.0,比起1.0(JSR 31)來,JAXB2(JSR 222)用JDK5的新特性Annotation來標識要作綁定的類和屬性等,這就極大簡化了開發的工作量。

實際上,在Java EE 5.0中,EJB和Web Services也通過Annotation來簡化開發工作。另外,JAXB2在底層是用StAX(JSR 173)來處理XML文檔。除了JAXB之外,我們還可以通過XMLBeans和Castor等來實現同樣的功能。


③ StAX

StAX(JSR 173)是JDK1.6.0中除了DOM和SAX之外的又一種處理XML文檔的API。

StAX 的來歷:在JAXP1.3(JSR 206)有兩種處理XML文檔的方法—DOM(Document Object Model)和SAX(Simple API for XML)。

JDK1.6.0中的JAXB2(JSR 222)和JAX-WS 2.0(JSR 224)都會用到StAX。Sun決定把StAX加入到JAXP家族當中來,並將JAXP的版本升級到1.4(JAXP1.4是JAXP1.3的維護版 本)。JDK1.6裏面JAXP的版本就是1.4。

StAX是The Streaming API for XML的縮寫,一種利用拉模式解析(pull-parsing)XML文檔的API。StAX通過提供一種基於事件迭代器(Iterator)的API讓 程序員去控制xml文檔解析過程,程序遍歷這個事件迭代器去處理每一個解析事件,解析事件可以看做是程序拉出來的,也就是程序促使解析器產生一個解析事件 然後處理該事件,之後又促使解析器產生下一個解析事件,如此循環直到碰到文檔結束符。

SAX也是基於事件處理xml文檔,但卻是用推模式解析,解析器解析完整個xml文檔後,才產生解析事件,然後推給程序去處理這些事件。

DOM採 用的方式是將整個xml文檔映射到一顆內存樹,這樣就可以很容易地得到父節點和子結點以及兄弟節點的數據,但如果文檔很大,將會嚴重影響性能.


④ 使用Compiler API

現在我們可以用JDK1.6 的Compiler API(JSR 199)去動態編譯Java源文件,Compiler API結合反射功能就可以實現動態的產生Java代碼並編譯執行這些代碼,有點動態語言的特徵。

這個特性對於某些需要用到動態編譯的應用程序相當有用,比如JSP Web Server,當我們手動修改JSP後,是不希望需要重啓Web Server纔可以看到效果的,這時候我們就可以用Compiler API來實現動態編譯JSP文件,當然,現在的JSP Web Server也是支持JSP熱部署的,現在的JSP Web Server通過在運行期間通過Runtime.exec或ProcessBuilder來調用javac來編譯代碼,這種方式需要我們產生另一個進程去 做編譯工作,不夠優雅容易使代碼依賴與特定的操作系統。

Compiler API通過一套易用的標準的API提供了更加豐富的方式去做動態編譯,是跨平臺的。


⑤ 量級Http Server API

JDK1.6 提供了一個簡單的Http Server API,據此我們可以構建自己的嵌入式Http Server,它支持Http和Https協議,提供了HTTP1.1的部分實現,沒有被實現的那部分可以通過擴展已有的Http Server API來實現,程序員自己實現HttpHandler接口,HttpServer會調用HttpHandler實現類的回調方法來處理客戶端請求,在這 裏,我們把一個Http請求和它的響應稱爲一個交換,包裝成HttpExchange類,HttpServer負責將HttpExchange傳給 HttpHandler實現類的回調方法.


⑥插入式註解處理API(Pluggable Annotation Processing API)

插入式註解處理API(JSR 269)提供一套標準API來處理Annotations(JSR 175)。

實際上JSR 269不僅僅用來處理Annotation,我覺得更強大的功能是它建立了Java 語言本身的一個模型,它把method,package,constructor,type,variable, enum,annotation等Java語言元素映射爲Types和Elements(兩者有什麼區別?),從而將Java語言的語義映射成爲對象,我 們可以在javax.lang.model包下面可以看到這些類. 我們可以利用JSR 269提供的API來構建一個功能豐富的元編程(metaprogramming)環境。

JSR 269用Annotation Processor在編譯期間而不是運行期間處理Annotation,Annotation Processor相當於編譯器的一個插件,稱爲插入式註解處理。如果Annotation Processor處理Annotation時(執行process方法)產生了新的Java代碼,編譯器會再調用一次Annotation Processor,如果第二次處理還有新代碼產生,就會接着調用Annotation Processor,直到沒有新代碼產生爲止.每執行一次process()方法被稱爲一個"round",這樣整個Annotation processing過程可以看作是一個round的序列。

JSR 269主要被設計成爲針對Tools或者容器的API. 舉個例子,我們想建立一套基於Annotation的單元測試框架(如TestNG),在測試類裏面用Annotation來標識測試期間需要執行的測試方法.


⑦ 用Console開發控制檯程序

JDK1.6中提供了java.io.Console 類專用來訪問基於字符的控制檯設備。你的程序如果要與Windows下的cmd或者Linux下的Terminal交互,就可以用Console類代勞。 但我們不總是能得到可用的Console,一個JVM是否有可用的Console依賴於底層平臺和JVM如何被調用。如果JVM是在交互式命令行(比如 Windows的cmd)中啓動的,並且輸入輸出沒有重定向到另外的地方,那麼就可以得到一個可用的Console實例。

⑧ 對腳本語言的支持

如: ruby,groovy,javascript


⑨ Common Annotations

Common annotations原本是Java EE 5.0(JSR 244)規範的一部分,現在SUN把它的一部分放到了Java SE 6.0中。

隨着Annotation元數據功能(JSR 175)加入到Java SE 5.0裏面,很多Java 技術(比如EJB,Web Services)都會用Annotation部分代替XML文件來配置運行參數(或者說是支持聲明式編程,如EJB的聲明式事務),如果這些技術爲通用 目的都單獨定義了自己的Annotations,顯然有點重複建設。爲其他相關的Java技術定義一套公共的Annotation是有價值的,可以避免 重複建設的同時,也保證Java SE和Java EE 各種技術的一致性。


【4】JDK1.7

主要特性有:

  • 自動資源管理;
  • 改進的通用實例創建類型推斷;
  • 數字字面量下劃線支持;
  • switch中使用string;
  • 二進制字面量;
  • 簡化可變參數方法調用;
  • 引入Java NIO.2開發包。

首先說明一點,網上所說的所謂jdk1.7新特性中對“集合類語言的支持”是錯的,實踐證明並不可以,官網也並沒有說該特性,不少博客以訛傳訛。

① 自動資源管理

Java中某些資源是需要手動關閉的,如InputStream,Writes,Sockets,Sql classes等。這個新的語言特性允許try語句本身申請更多的資源, 這些資源作用於try代碼塊,並自動關閉。

實例如下:

BufferedReader br = new BufferedReader(new FileReader(path)); 
 try { 
    return br.readLine(); 
  } finally { 
     br.close(); 
} 

修改爲如下:

 try (BufferedReader br = new BufferedReader(new FileReader(path)) { 
  return br.readLine(); 
 } 

可以定義關閉多個資源:

try ( 
   InputStream in = new FileInputStream(src); 
    OutputStream out = new FileOutputStream(dest)) 
{ 
// code 
} 

爲了支持這個行爲,所有可關閉的類將被修改爲實現一個Closable(可關閉的)接口。
在這裏插入圖片描述


② 增強的對通用實例創建(diamond)的類型推斷

類型推斷是一個特殊的煩惱,下面的代碼:

Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); 

通過類型推斷後變成:

 Map<String, List<String>> anagrams = new HashMap<>(); 

這個<>被叫做diamond(鑽石)運算符,這個運算符從引用的聲明中推斷類型。


③ 數字字面量下劃線支持

很長的數字可讀性不好,在Java 7中可以使用下劃線分隔長int以及long了,如:

   int one_million = 1_000_000; 

運算時先去除下劃線,如:1_1 * 10 = 110,120 – 1_0 = 110


④ switch中使用string

以前你在switch中只能使用number或enum。現在可以使用string了:

String s = ... 
switch(s) { 
 case "quux": 
      processQuux(s); 
case "foo": 
case "bar": 
      processFooOrBar(s); 
  break; 
case "baz": 
	processBaz(s); 
default: 
        processDefault(s); 
        break; 
} 

⑤ 二進制字面量

由於繼承C語言,Java代碼在傳統上迫使程序員只能使用十進制,八進制或十六進制來表示數(numbers)。

由於很少的域是以bit導向的,這種限制可能導致錯誤。現在,你可以使用二進制字面量這種表示方式,並且使用非常簡短的代碼,可將二進制字符轉換爲數據類型,如在byte或short。

byte aByte = (byte)0b001;    
short aShort = (short)0b010;   
int binary = 0b1001_1001; 

⑥ 簡化的可變參數調用

當程序員試圖使用一個不可具體化的可變參數並調用一個varargs(可變)方法時,編輯器會生成一個“非安全操作”的警告。

JDK 7將警告從call轉移到了方法聲明(methord declaration)的過程中。這樣API設計者就可以使用vararg,因爲警告的數量大大減少了。


⑦ NIO

NIO即非阻塞IO,Java NIO(New IO)是從Java 1.4版本開始引入的一個新的IO API,可以替代標準的Java IO API。隨着JDK 7 的發佈,Java對NIO進行了極大的擴展,增強了對文件處理和文件系統特性的支持,以至於我們稱他們爲NIO.2。因爲NIO 提供的一些功能,NIO已經成爲文件處理中越來越重要的部分。

關於NIO和NIO2.0特性參考博文:IO/NIO那些事


【5】JDK1.8

Java 8 (又稱爲 jdk 1.8) 是 Java 語言開發的一個主要版本。 Java 8 是oracle公司於2014年3月發佈,可以看成是自Java 5 以來最具革命性的版本。Java 8爲Java語言、編譯器、類庫、開發工具與JVM帶來了大量新特性。

主要特性有:

  • 接口的默認方法
  • Lambda 表達式
  • 函數式接口
  • 方法與構造函數引用
  • Lambda 作用域
  • 訪問局部變量
  • 訪問對象字段與靜態變量
  • 訪問接口的默認方法
  • Date API
  • Annotation 註解

① Lambda作用域

在lambda表達式中訪問外層作用域和老版本的匿名對象中的方式很相似。你可以直接訪問標記了final的外層局部變量,或者實例的字段以及靜態變量。

② Lambda訪問局部變量

可以直接在lambda表達式中訪問外層的局部變量。

代碼如下:

final int num = 1;
Converter<Integer, String> stringConverter =
        (from) -> String.valueOf(from + num);

stringConverter.convert(2);     // 3

但是和匿名對象不同的是,這裏的變量num可以不用聲明爲final,該代碼同樣正確。

代碼如下:

int num = 1;
Converter<Integer, String> stringConverter =
        (from) -> String.valueOf(from + num);
stringConverter.convert(2);     // 3

不過這裏的num必須不可被後面的代碼修改(即隱性的具有final的語義),例如下面的就無法編譯:

int num = 1;
Converter<Integer, String> stringConverter =
        (from) -> String.valueOf(from + num);
num = 3;

在lambda表達式中試圖修改num同樣是不允許的。


③ Lambda訪問對象字段與靜態變量

和本地變量不同的是,lambda內部對於實例的字段以及靜態變量是即可讀又可寫。該行爲和匿名對象是一致的:

class Lambda4 {
    static int outerStaticNum;
    int outerNum;
 
    void testScopes() {
        Converter<Integer, String> stringConverter1 = (from) -> {
            outerNum = 23;
            return String.valueOf(from);
        };
 
        Converter<Integer, String> stringConverter2 = (from) -> {
            outerStaticNum = 72;
            return String.valueOf(from);
        };
    }
}

④ Lambda訪問接口的默認方法

Lambda表達式中是無法訪問到默認方法的,以下代碼將無法編譯:

Formula formula = (a) -> sqrt( a * 100);
//Built-in Functional Interfaces

⑤ Map提供的函數

Map類型不支持stream,不過Map提供了一些新的有用的方法來處理一些日常任務。

實例如下:

Map<Integer, String> map = new HashMap<>();
 
for (int i = 0; i < 10; i++) {
    map.putIfAbsent(i, "val" + i);
}
map.forEach((id, val) -> System.out.println(val));

以上代碼很容易理解, putIfAbsent 不需要我們做額外的存在性檢查,而forEach則接收一個Consumer接口來對map裏的每一個鍵值對進行操作。

下面的例子展示了map上的其他有用的函數:

map.computeIfPresent(3, (num, val) -> val + num);
map.get(3);             // val33
 
map.computeIfPresent(9, (num, val) -> null);
map.containsKey(9);     // false
 
map.computeIfAbsent(23, num -> "val" + num);
map.containsKey(23);    // true
 
map.computeIfAbsent(3, num -> "bam");
map.get(3);             // val33

map.getOrDefault(42, "not found");  // not found

接下來展示如何在Map裏刪除一個鍵值全都匹配的項:

map.remove(3, "val3");
map.get(3);             // val33
 
map.remove(3, "val33");
map.get(3);             // null

對Map的元素做合併也變得很容易了:

map.merge(9, "val9", (value, newValue) -> value.concat(newValue));
map.get(9);             // val9
 
map.merge(9, "concat", (value, newValue) -> value.concat(newValue));
map.get(9);             // val9concat

Merge做的事情是如果鍵名不存在則插入,否則則對原鍵對應的值做合併操作並重新插入到map中。

jdk1.8的其他特性詳解講解參考博客:JDK1.8新特性一二三


【6】JDK1.9

經過4次跳票,歷經曲折的java 9 終於終於在2017年9月21日發佈。java 9 提供了超過150項新功能特性,包括備受期待的模塊化系統、可交互的 REPL 工具:jshell,JDK 編譯工具,Java 公共 API 和私有代碼,以及安全增強、擴展提升、性能管理改善等。可以說Java 9是一個龐大的系統工程,完全做了一個整體改變。

主要特性具體來講:

  • 模塊化系統
  • jShell命令
  • 多版本兼容jar包
  • 接口的私有方法
  • 鑽石操作符的使用升級
  • 語法改進:try語句
  • 下劃線使用限制
  • String存儲結構變更
  • 便利的集合特性:of()
  • 增強的Stream API
  • 多分辨率圖像 API
  • 全新的HTTP客戶端API
  • Deprecated的相關API
  • 智能Java編譯工具
  • 統一的JVM日誌系統
  • javadoc的HTML 5支持
  • Javascript引擎升級:Nashorn
  • java的動態編譯器

【7】JDK1.10

根據官網的公開資料,共有12個重要特性,如下:

  • JEP286,var 局部變量類型推斷。
  • JEP296,將原來用 Mercurial 管理的衆多 JDK 倉庫代碼,合併到一個倉庫中,簡化開發和管理過程。
  • JEP304,統一的垃圾回收接口。
  • JEP307,G1 垃圾回收器的並行完整垃圾回收,實現並行性來改善最壞情況下的延遲。
  • JEP310,應用程序類數據 (AppCDS) 共享,通過跨進程共享通用類元數據來減少內存佔用空間,和減少啓動時間。
  • JEP312,ThreadLocal 握手交互。在不進入到全局 JVM 安全點 (Safepoint) 的情況下,對線程執行回調。優化可以只停止單個線程,而不是停全部線程或一個都不停。
  • JEP313,移除 JDK 中附帶的 javah 工具。可以使用 javac -h 代替。
  • JEP314,使用附加的 Unicode 語言標記擴展。
  • JEP317,能將堆內存佔用分配給用戶指定的備用內存設備。
  • JEP317,使用 Graal 基於 Java 的編譯器,可以預先把 Java 代碼編譯成本地代碼來提升效能。
  • JEP318,在 OpenJDK 中提供一組默認的根證書頒發機構證書。開源目前 Oracle 提供的的 Java SE 的根證書,這樣 OpenJDK 對開發人員使用起來更方便。
  • JEP322,基於時間定義的發佈版本,即上述提到的發佈週期。版本號爲\$FEATURE.\$INTERIM.\$UPDATE.\$PATCH,分別是大版本,中間版本,升級包和補丁版本。

【8】JDK1.11

翻譯後的新特性有:

  • 181:Nest-Based訪問控制
  • 309:動態類文件常量
  • 315:改善Aarch64 intrinsic
  • 318:無操作垃圾收集器
  • 320:消除Java EE和CORBA模塊
  • 321:HTTP客戶端(標準)
  • 323:局部變量的語法λ參數
  • 324:Curve25519和Curve448關鍵協議
  • 327:Unicode 10
  • 328:飛行記錄器
  • 329:ChaCha20和Poly1305加密算法
  • 330:發射一列縱隊源代碼程序
  • 331:低開銷堆分析
  • 332:傳輸層安全性(Transport Layer Security,TLS)1.3
  • 333:動作:一個可伸縮的低延遲垃圾收集器 (實驗)
  • 335:反對Nashorn JavaScript引擎
  • 336:反對Pack200工具和API

不定期整理分享。。

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