JDK各版本特性簡述
JDK1.2
1998年12月8日,第二代Java平臺的企業版J2EE發佈。
1999年6月,Sun公司發佈了第二代Java平臺(簡稱爲Java2)的3個版本:
J2ME(Java2 Micro Edition,Java2平臺的微型版):應用於移動、無線及有限資源的環境
J2SE(Java 2 Standard Edition,Java 2平臺的標準版):應用於桌面環境
J2EE(Java 2Enterprise Edition,Java 2平臺的企業版):應用於基於Java的應用服務器
Java 2平臺的發佈,是Java發展過程中最重要的一個里程碑,標誌着Java的應用開始普及
JDK1.5(代號Tiger)特性:
1. 泛型
在JDK1.5之前一個集合可以放任何類型的對象,相應地從集合裏面拿對象的時候我們也不得不對他們進行強制的類型轉換。引入了泛型之後,它允許指定集合裏元素的類型,這樣在編譯階段就會對對象進行類型檢查。
2. for-each循環
for(元素的數據類型 變量名 : 數組或集合){
}
3. 自動裝箱、自動拆箱
自動裝箱:基本類型自動轉爲包裝類
自動拆箱:包裝類自動轉爲基本類型
4. 枚舉
修飾符 enum 枚舉名{
變量名1,變量名2;
}
5. 可變參數
可變參數使程序員可以聲明一個接受可變數目參數的方法。
注意,可變參數必須是函數生命中的最後一個參數。
6. 靜態導入
同一個類中,調用靜態變量,方法,可以省略類名
7. 元數據
8.內省
主要用於操作JavaBean中的屬性,通過getXxx/setXxx。一般的做法是通過類Introspector來獲取某個對象的BeanInfo信息,然後通過BeanInfo來獲取屬性的描述器(PropertyDescriptor),通過這個屬性描述器就可以獲取某個屬性對應的getter/setter方法,然後我們就可以通過反射機制來調用這些方法。
9.協變返回類型
實際返回類型可以是要求的返回類型的一個子類型
JDK1.6 (代號Mustang)特性:
1. Desktop類和SystemTray
2. 使用JAXB2來實現對象與XML之間的映射
3. 理解StAX
一種利用拉模式解析(pull-parsing)XML文檔的API。類似於SAX,也基於事件驅動模型。之所以將StAX加入到JAXP家族,是因爲JDK6中的JAXB2和JAX-WS 2.0中都會用StAX
4. 使用Compiler API
使用Compiler API,動態編譯Java源文件,如JSP編譯引擎就是動態的,所以修改後無需重啓服務器
5. 輕量級Http Server API
輕量級Http Server API,據此可以構建自己的嵌入式HttpServer,它支持Http和Https協議
6. 插入式註解處理API
7. 用Console開發控制檯程序
提供了Console類用以開發控制檯程序,位於java.io包中。據此可方便與Windows下的cmd或Linux下的Terminal等交互
8. 對腳本語言的支持
如:ruby,groovy,,javascript
9. Common Annotations
Common Annotations,原是J2EE 5.0規範的一部分,現在把它的一部分放到了J2SE 6.0中
10.AWT新增加了兩個類
Desktop和SystemTray,其中前者用來通過系統默認程序來執行一個操作,如使用默認瀏覽器瀏覽指定的URL,用默認郵件客戶端給指定的郵箱發郵件,用默認應用程序打開或編輯文件(比如,用記事本打開以txt爲後綴名的文件),用系統默認的打印機打印文檔等。後者可以用來在系統托盤區創建一個托盤程序
JDK1.7 特性:
1. switch語句支持字符串變量
2. 泛型實例化類型自動推斷
//泛型聲明後邊的<>可以省略不寫泛型
ArrayList<String> list = new ArrayList<>();
3. 支持二進制數字字面量
從JDK1.7開始,可以用二進制來表示整數(byte,short,int和long)。使用二進制字面量的好處是,可以是代碼更容易被理解。語法非常簡單,只要在二進制數值前面加 0b或者0B。
4. 數字字面量可以出現下劃線
用下劃線連接整數提升其可讀性,自身無含義,不可用在數字的起始和末尾。
Java編碼語言對給數值型的字面值加下劃線有嚴格的規定。如上所述,你只能在數字之間用下劃線。你不能用把一個數字用下劃線開頭,或者已下劃線結尾。這裏有一些其它的不能在數值型字面值上用下劃線的地方:
- 在數字的開始或結尾
- 對浮點型數字的小數點附件
- F或L下標的前面
- 該數值型字面值是字符串類型的時候
float pi1 = 3_.1415F; // 無效的; 不能在小數點之前有下劃線
float pi2 = 3._1415F; // 無效的; 不能在小數點之後有下劃線
long socialSecurityNumber1=999_99_9999_L;//無效的,不能在L下標之前加下劃線
int a1 = _52; // 這是一個下劃線開頭的標識符,不是個數字
int a2 = 5_2; // 有效
int a3 = 52_; // 無效的,不能以下劃線結尾
int a4 = 5_______2; // 有效的
int a5 = 0_x52; // 無效,不能在0x之間有下劃線
int a6 = 0x_52; // 無效的,不能在數字開頭有下劃線
int a7 = 0x5_2; // 有效的 (16進制數字)
int a8 = 0x52_; // 無效的,不能以下劃線結尾
int a9 = 0_52; // 有效的(8進制數)
int a10 = 05_2; // 有效的(8進制數)
int a11 = 052_; // 無效的,不能以下劃線結尾
5. 單個catch中捕獲多個異常
在Java 7中,catch代碼塊得到了升級,用以在單個catch塊中處理多個異常。如果你要捕獲多個異常並且它們包含相似的代碼,使用這一特性將會減少代碼重複度。下面用一個例子來理解。
catch(IOException | SQLException | Exception ex){
logger.error(ex);
throw new MyException(ex.getMessage());
}
6. try-with-resources語句
try-with-resources語句是一個聲明一個或多個資源的try語句。一個資源作爲一個對象,必須在程序結束之後關閉。try-with-resources語句確保在語句的最後每個資源都被關閉,任何實現了Java.lang.AutoCloseable和java.io.Closeable的對象都可以使用try-with-resource來實現異常處理和關閉資源。
JDK1.7之前
/**
* JDK1.7之前我們必須在finally塊中手動關閉資源,否則會導致資源的泄露
* @author Liao
*
*/
public class PreJDK7 {
public static String readFirstLingFromFile(String path) throws IOException {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(path));
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
} finally {//必須在這裏關閉資源
if (br != null)
br.close();
}
return null;
}
}
JDK1.7之後
/**
* JDK1.7之後就可以使用try-with-resources,不需要 我們在finally塊中手動關閉資源
*
* @author Liao
*/
public class AboveJDK7 {
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
}
JDK1.8 特性:
1. 接口可以添加默認方法
修飾符 default 返回值類型 方法名(參數列表){
方法體;
}
2. Lambda表達式
@Test
public void test2() {
// 如果用Lambda表達式,一定要寫明泛型
List<String> list = Arrays.asList("peter","anna","make");
// ①.老版本的Java中是這樣排列字符串的
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.compareTo(b);
}
});
// ②.Java 8提供了更簡潔的語法,lambda表達式:
/*
Collections.sort(list ,(String a,String b) -> {
return a.compareTo(b);
});
// ③.還可以寫得更短
Collections.sort(list, (String a, String b) -> a.compareTo(b));
// ④.還可以這麼寫
Collections.sort(list, String::compareTo);
System.out.println(Collections.singletonList(list)); //[[anna, make, peter]]
}
什麼是λ表達式
λ表達式本質上是一個匿名方法。讓我們來看下面這個例子:
public int add(int x, int y) {
return x + y;
}
轉成λ表達式後是這個樣子:
(int x, int y) -> x + y;
參數類型也可以省略,Java編譯器會根據上下文推斷出來:
(x, y) -> x + y; //返回兩數之和
或者
(x, y) -> { return x + y; } //顯式指明返回值
可見λ表達式有三部分組成:
1、參數列表
2、箭頭(->)
3、以及一個表達式或語句塊。
3. 函數式接口
4. 方法引用
通常與Lambda表達式聯合使用,可以直接引用已有Java類或對象的方法。
一般有四種不同的方法引用:
1、構造器引用。語法是Class::new,或者更一般的Class< T >::new,要求構造器方法是沒有參數;
2、靜態方法引用。語法是Class::static_method,要求接受一個Class類型的參數;
3、特定類的任意對象方法引用。它的語法是Class::method。要求方法是沒有參數的;
4、特定對象的方法引用,它的語法是instance::method。要求方法接受一個參數,與3不同的地方在於,3是在列表元素上分別調用方法,而4是在某個對象上調用方法,將列表元素作爲參數傳入。
5. 重複註解
在Java 5中使用註解有一個限制,即相同的註解在同一位置只能聲明一次。Java 8引入重複註解,這樣相同的註解在同一地方也可以聲明多次。重複註解機制本身需要用@Repeatable註解。Java 8在編譯器層做了優化,相同註解會以集合的方式保存,因此底層的原理並沒有變化。
6. 擴展註解的支持
Java 8擴展了註解的上下文,幾乎可以爲任何東西添加註解,包括局部變量、泛型類、父類與接口的實現,連方法的異常也能添加註解。
7. Optional
Java 8引入Optional類來防止空指針異常,Optional類最先是由Google的Guava項目引入的。Optional類實際上是個容器:它可以保存類型T的值,或者保存null。使用Optional類我們就不用顯式進行空指針檢查了。
8. Stream
Stream API是把真正的函數式編程風格引入到Java中。其實簡單來說可以把Stream理解爲MapReduce,當然Google的MapReduce的靈感也是來自函數式編程。她其實是一連串支持連續、並行聚集操作的元素。從語法上看,也很像linux的管道、或者鏈式編程,代碼寫起來簡潔明瞭,非常酷帥。
9. Date/Time API (JSR 310)
Java 8新的Date-Time API (JSR 310)受Joda-Time的影響,提供了新的java.time包,可以用來替代 java.util.Date和java.util.Calendar。一般會用到Clock、LocaleDate、LocalTime、LocaleDateTime、ZonedDateTime、Duration這些類,對於時間日期的改進還是非常不錯的。
10. JavaScript引擎Nashorn
Nashorn允許在JVM上開發運行JavaScript應用,允許Java與JavaScript相互調用。
11. Base64
在Java 8中,Base64編碼成爲了Java類庫的標準。Base64類同時還提供了對URL、MIME友好的編碼器與解碼器。