SE(J2SE),standard edition,標準版,是咱們一般用的一個版本,從JDK 5.0開始,更名爲Java SE。html
EE(J2EE),enterprise edition,企業版,使用這種JDK開發J2EE應用程序,從JDK 5.0開始,更名爲Java EE。java
ME(J2ME),micro edition,主要用於移動設備、嵌入式設備上的java應用程序,從JDK 5.0開始,更名爲Java ME。git
沒有JDK的話,沒法編譯Java程序,若是想只運行Java程序,要確保已安裝相應的JRE。程序員
如下是各版本的名稱及發佈日期:數據庫
版本編程 |
名稱瀏覽器 |
發行日期安全 |
JDK 1.1.4服務器 |
Sparkler(寶石)網絡 |
1997-09-12 |
JDK 1.1.5 |
Pumpkin(南瓜) |
1997-12-13 |
JDK 1.1.6 |
Abigail(阿比蓋爾–女子名) |
1998-04-24 |
JDK 1.1.7 |
Brutus(布魯圖–古羅馬政治家和將軍) |
1998-09-28 |
JDK 1.1.8 |
Chelsea(切爾西–城市名) |
1999-04-08 |
J2SE 1.2 |
Playground(運動場) |
1998-12-04 |
J2SE 1.2.1 |
none(無) |
1999-03-30 |
J2SE 1.2.2 |
Cricket(蟋蟀) |
1999-07-08 |
J2SE 1.3 |
Kestrel(美洲紅隼) |
2000-05-08 |
J2SE 1.3.1 |
Ladybird(瓢蟲) |
2001-05-17 |
J2SE 1.4.0 |
Merlin(灰背隼) |
2002-02-13 |
J2SE 1.4.1 |
grasshopper(蚱蜢) |
2002-09-16 |
J2SE 1.4.2 |
Mantis(螳螂) |
2003-06-26 |
Java SE 5.0 (1.5.0) |
Tiger(老虎) |
2004-09-30 |
Java SE 6.0 (1.6.0) |
Mustang(野馬) |
2006-04 |
Java SE 7.0 (1.7.0) |
Dolphin(海豚) |
2011-07-28 |
Java SE 8.0 (1.8.0) |
未知 |
2013-09(預約) |
Collection<String> c = new ArrayList(); c.add(new Date()); |
編譯器會給出一個錯誤:
add(java.lang.String) in java.util.Collection<java.lang.String> cannot be applied to (java.util.Date) |
2.For-Each循環
For-Each循環得加入簡化了集合的遍歷。假設咱們要遍歷一個集合對其中的元素進行一些處理。典型的代碼爲:
void processAll(Collection c){ for(Iterator i=c.iterator(); i.hasNext();){ MyClass myObject = (MyClass)i.next(); myObject.process(); } } |
使用For-Each循環,咱們能夠把代碼改寫成:
void processAll(Collection<MyClass> c){ for (MyClass myObject :c) myObject.process(); } |
這段代碼要比上面清晰許多,而且避免了強制類型轉換。
3.自動裝包/拆包(Autoboxing/unboxing)
自動裝包/拆包大大方便了基本類型數據和它們包裝類地使用。
自動裝包:基本類型自動轉爲包裝類.(int >> Integer)
自動拆包:包裝類自動轉爲基本類型.(Integer >> int)
在JDK1.5以前,咱們老是對集合不能存放基本類型而耿耿於懷,如今自動轉換機制解決了咱們的問題。
int a = 3; Collection c = new ArrayList(); c.add(a);//自動轉換成Integer. Integer b = new Integer(2); c.add(b + 2); |
public enum Color { Red, White, Blue } |
for (Color c : Color.values()) System.out.println(c); |
util.write(obj1); util.write(obj1,obj2); util.write(obj1,obj2,obj3); … |
public void write(Object... objs) { for (Object obj: objs) System.out.println(obj); } |
import static java.lang.Math.*; ……. r = sin(PI * 2); //無需再寫r = Math.sin(Math.PI); |
Collection<String> c = new ArrayList(); c.add(new Date()); |
編譯器會給出一個錯誤:
add(java.lang.String) in java.util.Collection<java.lang.String> cannot be applied to (java.util.Date) |
Java SE 6.0 (1.6.0) |
Mustang(野馬)的新特性 |
簡化Web Services
Mustang 將 簡化Web services 的開發和發佈. XML和Web服務一直都是Mustang的關注重點.. Mustang爲此引入了JAX-WS(Java Architecture for XML-Web Services) 2.0 以及JAXB(Java Architecture for XML Binding) 2.0.. 同時還有Streaming API for XML (STaX), 它提供了一個雙向API,這個API能夠經過一個事件流來讀取或者寫入XML,其中包括跳過某個部分,而後直接關注與文檔中的另一個小部分的能力。
Scripting,整合腳本語言
目前來說,Java 開發者們必須在Java以外獨立地額外編碼來使用non-Java 腳本語言。這個頭痛的問題將被Mustang 消滅,開發者將更加輕鬆的使用Perl、PHP、Python、JavaScript 和Ruby等腳本語言。新的框架將容許人們操做任意的腳本語言,和使用Java 對象。
Java SE6中實現了JSR223。這是一個腳本框架,提供了讓腳本語言來訪問Java內部的方法。你能夠在運行的時候找到腳本引擎,而後調用這個引擎去執行腳本。這個腳本API容許你爲腳本語言提供Java支持。另外,Web Scripting Framework容許腳本代碼在任何的Servlet容器(例如Tomcat)中生成Web內容。
Database,綁定Derby
開源嵌入式數據庫 Derby(JavaDB) 綁定在JDK 1.6中.具體能夠參考:JDK 1.6 將綁定開源數據庫 Derby
更豐富的Desktop APIs
Mustang中擁有更多強的桌面API提供給開發者, 開發者能夠更簡單地開發更強大的桌面應用, 好比啓動界面的支持,系統托盤的支持,JTable排序等等
監視和管理
Java SE 6中對內存泄漏加強了分析以及診斷能力。當遇到java.lang.OutOfMemory異常的時候,能夠獲得一個完整的堆棧信息,而且當堆已經滿了的時候,會產生一個Log文件來記錄這個致命錯誤。另外,JVM還添加了一個選項,容許你在堆滿的時候運行腳本。(這也就是提供了另一種方法來診斷錯誤)
加強的JMX 監視API在MBean的屬性值傳入了一個特定的參數的時候,容許這個應用程序發送一個事件通告。(這裏的屬性值能夠在很複雜的類型中)
對於Solaris 10的用戶,爲Solaris提供的Hotspot JVM中,提供了一種經過Solaris DTrace(這是個系統的調試工具)來追蹤顯示JVM內部的活動狀況,包括垃圾收集,類裝載,線程,鎖等等。
Pluggable Annotations
從Java SE 5 帶來得新特性Annotations,將在Mustang繼續扮演重要角色..
Compiler API:訪問編譯器
對於Java開發工具, 或者Web框架 等的開發者來講, 利用編譯器編譯動態生成的代碼, 是一個廣泛的需求.
Mustang實現了JSR 199, 提供了Java編譯器API(應用程序接口),容許你從一個Java應用程序中去編譯其餘的Java源程序--好比在應用程序中動態生成的一些源代碼..
Security:安全性
Java SE 6的安所有分,增長了 XML-Digital Signature (XML-DSIG) APIs, 整合了GSS/Kerberos的操做API,LDAP上的JAAS認證。
Instrumentation
利用 Java 代碼,即 java.lang.instrument 作動態 Instrumentation 是 Java SE 5 的新特性,它把 Java 的 instrument 功能從本地代碼中解放出來,使之能夠用 Java 代碼的方式解決問題。在 Java SE 6 裏面,instrumentation 包被賦予了更強大的功能:啓動後的 instrument、本地代碼(native code)instrument,以及動態改變 classpath 等等。在 Java SE 5 當中,開發者只能在 premain 當中施展想象力,所做的 Instrumentation 也僅限與 main 函數執行前,這樣的方式存在必定的侷限性。在 Java SE 6 的 Instrumentation 當中,有一個跟 premain「並駕齊驅」的「agentmain」方法,能夠在 main 函數開始運行以後再運行。
Http
在 Java SE 6 當中,圍繞着 HTTP 協議出現了不少實用的新特性:NTLM 認證提供了一種 Window 平臺下較爲安全的認證機制;JDK 當中提供了一個輕量級的 HTTP 服務器;提供了較爲完善的 HTTP Cookie 管理功能;更爲實用的 NetworkInterface;DNS 域名的國際化支持等等。
HTTP Cookie管理能夠應用客戶操做臨時變量的保存,如查詢條件,當前狀態等
JMX與系統管理
Agent / SubAgent 起到的就是翻譯的做用:把 IT 資源報告的消息以管理系統能理解的方式傳送出去。
也許讀者有會問,爲何須要 Agent 和 SubAgent 兩層體系呢?這裏有兩個現實的緣由:
管理系統通常是一箇中央控制的控制軟件,而 SubAgent 直接監控一些資源,每每和這些資源分佈在同一物理位置。當這些 SubAgent 把狀態信息傳輸到管理系統或者傳達管理系統的控制指令的時候,須要提供一些網絡傳輸的功能。
通常來講,管理系統會將同一物理分佈或者功能相似的 SubAgent 分組成一組,由一個共用的 Agent 加以管理。在這個 Agent 裏封裝了 1 和 2 的功能。
JMX 和管理系統
JMX 既是 Java 管理系統的一個標準,一個規範,也是一個接口,一個框架
JMX 是管理系統和資源之間的一個接口,它定義了管理系統和資源之間交互的標準。javax.management.MBeanServer
實現了 Agent 的功能,以標準的方式給出了管理系統訪問 JMX 框架的接口。而 javax.management.MBeans
實現了 SubAgent 的功能,以標準的方式給出了 JMX 框架訪問資源的接口。而從類庫的層次上看,JMX 包括了核心類庫 java.lang.management
和 javax.management
包。java.lang.management
包提供了基本的 VM 監控功能,而 javax.management
包則向用戶提供了擴展功能。 JMX幫助開發者監控JVM的信息。
編輯器API
JDK 6 提供了在運行時調用編譯器的 API。在傳統的 JSP 技術中,服務器處理 JSP 一般須要進行下面 6 個步驟:
但若是採用運行時編譯,能夠同時簡化步驟 4 和 5,節約新進程的開銷和寫入存儲器的輸出開銷,提升系統效率。實際上,在 JDK 5 中,Sun 也提供了調用編譯器的編程接口。然而不一樣的是,老版本的編程接口並非標準 API 的一部分,而是做爲 Sun 的專有實現提供的,而新版則帶來了標準化的優勢。
新 API 的第二個新特性是能夠編譯抽象文件,理論上是任何形式的對象 —— 只要該對象實現了特定的接口。有了這個特性,上述例子中的步驟 3 也能夠省略。整個 JSP 的編譯運行在一個進程中完成,同時消除額外的輸入輸出操做。
第三個新特性是能夠收集編譯時的診斷信息。做爲對前兩個新特性的補充,它可使開發人員輕鬆的輸出必要的編譯錯誤或者是警告信息,從而省去了不少重定向的麻煩
Java SE 7.0 (1.7.0) |
Dolphin(海豚)的新特性 |
一、Switch中可使用String了
在以前的版本中是不支持在Switch語句塊中用String類型的數據的,這個功能在C#語言中早已被支持,好在JDK1.7中加入了。
String s = "test"; switch (s) { case "test" : System.out.println("test"); case "test1" : System.out.println("test1"); break ; default : System.out.println("break"); break ; }
二、泛型實例化類型自動推斷
List<String> tempList = new ArrayList<>();
三、對Java 集合( Collections )的加強支持
在JDK1.7以前的版本中,Java集合容器中存取元素的形式以下。以List、Set、Map集合容器爲例:
//建立List接口對象 List<String> list=new ArrayList<String>(); list.add("item"); //用add()方法獲取對象 String Item=list.get(0); //用get()方法獲取對象 //建立Set接口對象 Set<String> set=new HashSet<String>(); set.add("item"); //用add()方法添加對象 //建立Map接口對象 Map<String,Integer> map=new HashMap<String,Integer>(); map.put("key",1); //用put()方法添加對象 int value=map.get("key")
在JDK1.7 中,摒棄了 Java 集合接口的實現類,如: ArrayList 、 HashSet 和 HashMap 。而是直接採用 [] 、{} 的形式存入對象,採用 [] 的形式按照索引、鍵值來獲取集合中的對象,以下:
List<String> list=["item"]; //向List集合中添加元素 String item=list[0]; //從List集合中獲取元素 Set<String> set={"item"}; //向Set集合對象中添加元素 Map<String,Integer> map={name:"xxx",age:18}; //向Map集合中添加對象 int value=map["age"]; //從Map集合中獲取對象
四、新增一些取環境信息的工具方法
File System.getJavaIoTempDir() // IO臨時文件夾 File System.getJavaHomeDir() // JRE的安裝目錄 File System.getUserHomeDir() // 當前用戶目錄 File System.getUserDir() // 啓動java進程時所在的目錄 ……
五、Boolean類型反轉,空指針安全,參與位運算
//類型反轉,空指針安全 Boolean Booleans.negate(Boolean booleanObj) //True => False , False => True, Null => Null //參與位運算boolean Booleans.and(boolean[] array) boolean Booleans.or(boolean[] array) boolean Booleans.xor(boolean[] array) boolean Booleans.and(Boolean[] array) boolean Booleans.or(Boolean[] array) boolean Booleans.xor(Boolean[] array)
六、兩個char間的equals
boolean Character.equalsIgnoreCase(char ch1, char ch2)
七、安全的加減乘除
int Math.safeToInt(long value) int Math.safeNegate(int value) long Math.safeSubtract(long value1, int value2) long Math.safeSubtract(long value1, long value2) int Math.safeMultiply(int value1, int value2) long Math.safeMultiply(long value1, int value2) long Math.safeMultiply(long value1, long value2) long Math.safeNegate(long value) int Math.safeAdd(int value1, int value2) long Math.safeAdd(long value1, int value2) long Math.safeAdd(long value1, long value2) int Math.safeSubtract(int value1, int value2)
八、數值可加下劃線
int one_million = 1_000_000;
九、支持二進制文字
int binary = 0b1001_1001;
能夠用二進制表達數字(加前綴0b/0B),包括:byte, short, int, long
// 能夠用二進制表達數字(加前綴0b/0B),包括:byte, short, int, long @Test public void testLiterals() { // An 8-bit 'byte' value: byte aByte = (byte)0b00100001; // A 16-bit 'short' value: short aShort = (short)0b1010000101000101; // Some 32-bit 'int' values: int anInt1 = 0b10100001010001011010000101000101; int anInt2 = 0b101; int anInt3 = 0B101; // The B can be upper or lower case. // A 64-bit 'long' value. Note the "L" suffix: long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L; // 來個簡單版本的 byte b = 0b10; short s = 0B100; int i = 0b1000; long l = 0B10000; System.out.println(b + "|" + s + "|" + i + "|" + l); // ->輸出將會是2|4|8|16 }
能夠對數字加下劃線以讓變量表達得更清楚些;注意:符號「.」左右不能夠用下劃線、還包括「L/F/0x"等等。
// 能夠對數字加下劃線以讓變量表達得更清楚些 // 注意:符號「.」左右不能夠用下劃線、還包括「L/F/0x"等等。 @Test public void testUnderscores() { long creditCardNumber = 1234_5678_9012_3456L; long socialSecurityNumber = 999_99_9999L; float pi = 3.14_15F; long hexBytes = 0xFF_EC_DE_5E; long hexWords = 0xCAFE_BABE; long maxLong = 0x7fff_ffff_ffff_ffffL; byte nybbles = 0b0010_0101; long bytes = 0b11010010_01101001_10010100_10010010; System.out.println(creditCardNumber + "|" + socialSecurityNumber); // ->下劃線僅供代碼中直觀查看,輸出時自動去掉了;輸出將會是:1234567890123456|999999999 }
// switch中可使用字符串了 public String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) { String typeOfDay; switch (dayOfWeekArg) { case "Monday": typeOfDay = "Start of work week"; break; case "Tuesday": case "Wednesday": case "Thursday": typeOfDay = "Midweek"; break; case "Friday": typeOfDay = "End of work week"; break; case "Saturday": case "Sunday": typeOfDay = "Weekend"; break; default: throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg); } return typeOfDay; }
// 泛型實例化類型自動推斷 @Test public void testGeneric() { // 舊版本 Map<String, List<String>> myMap1 = new HashMap<String, List<String>>(); // 新版本 Map<String, List<String>> myMap2 = new HashMap<>(); List<String> list = new ArrayList<>(); list.add("A"); // 下面這條語句編譯不過;若是改爲:new ArrayList<String>()則能夠。 // list.addAll(new ArrayList<>()); }
當使用一個不可具體化的參數(Non-Reifiable Formal Parameters)調用一個可變參數方法(Varargs Methods )編輯器會生成一個「非安全操做」的警告。
package com.clzhang.sample.thinking; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Test; /** * 當使用一個不可具體化的參數(Non-Reifiable Formal Parameters)調用一個可變參數方法(Varargs Methods ) * 編輯器會生成一個「非安全操做」的警告。 * @author acer * */public class ArrayBuilder { //Type safety: Potential heap pollution via varargs parameter elements public static <T> void addToList(List<T> listArg, T... elements) { for (T x : elements) { listArg.add(x); } } //Type safety: Potential heap pollution via varargs parameter l @SafeVarargs public static void faultyMethod(List<String>... l) { Object[] objectArray = l; // Valid // 這一行代碼把列表中的數據類型給改變了! objectArray[0] = Arrays.asList(new Integer(42)); // 下面再取值,會報錯;由於裏面已經再也不是String類型的數據,而是Integer類型的數據。 String s = l[0].get(0); // ClassCastException thrown here // 若是註釋掉本方法中的第2行代碼,則此條語句能夠執行;不然,執行不到這裏。 System.out.println("first param is:" + s); } @Test public void testHeapPollution() { List<String> stringListA = new ArrayList<String>(); List<String> stringListB = new ArrayList<String>(); ArrayBuilder.addToList(stringListA, "Seven", "Eight", "Nine"); ArrayBuilder.addToList(stringListA, "Ten", "Eleven", "Twelve"); List<List<String>> listOfStringLists = new ArrayList<List<String>>(); ArrayBuilder.addToList(listOfStringLists, stringListA, stringListB); ArrayBuilder.faultyMethod(Arrays.asList("Hello!"), Arrays.asList("World!")); } }
// JDK1.7以前的作法,須要在finally塊中關閉相關資源 String readFirstLineFromFileWithFinallyBlock(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { if (br != null) br.close(); } } // JDK1.7中已經不須要手工關閉這些資源了,JRE自動關閉這些資源。 // 一個對象實現了java.lang.AutoCloseable接口,或者是包含的全部對象實現了java.io.Closeable接口,便可以做爲一個資源來使用。 String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } } @Test public void testAutoClose() throws Exception { String path = "D:\\TDDOWNLOAD\\readme.txt"; System.out.println(readFirstLineFromFileWithFinallyBlock(path)); System.out.println(readFirstLineFromFile(path)); }
看下面這段代碼:
catch (IOException ex) { logger.log(ex); throw ex; catch (SQLException ex) { logger.log(ex); throw ex; }
在JDK1.7中,上述代碼能夠改寫爲:
catch (IOException|SQLException ex) { logger.log(ex); throw ex; }
看下面這段代碼:
static class FirstException extends Exception { } static class SecondException extends Exception { } public void rethrowException(String exceptionName) throws Exception { try { if (exceptionName.equals("First")) { throw new FirstException(); } else { throw new SecondException(); } } catch (Exception e) { throw e; } }
在以前 JDK版本中,它不能夠:throws FirstException, SecondException。而在JDK1.7中,它能夠了,以下:
public void rethrowException(String exceptionName) throws FirstException, SecondException { try { // ... } catch (Exception e) { throw e; } }