JDK1.5 JDK1.6 各自的新特性

xyang81 14年前發布 | 6K 次閱讀 云計算

<DIV style="FONT-SIZE: 16px" id=blogDetailDiv>

自己一直用JDK1.5,一個同學突然問我JDK1.5和之前的版本有什么區別嗎?我無語了,自己感覺對JAVA了解的還可以,可這一個這么基本的問題都不會...,回來再谷歌上百度一下,總結下:

JDK1.5(JDK5.0)

Java2標準版(Java 2 Platform, Standard Edition, J2SE)1.5版本更新不同于以往,它帶來了很多里程碑式的革新,SUN將其綽號取名為“虎”。這一次的變革將是Java誕生以來從未有過的,它給我們帶來了耳目一新的感覺。下面我們就來欣賞一下其中的部分典型變化:

比較JDK版本,JDK 1.5中新增的語言特性:

1.枚舉(增加了一個關鍵字enum);

2.變參(方法參數數量可以不固定多少);

3.泛型;

4.自動拆裝箱(基本類型與包裝類型可以混用);

5.foreach循環(方法地用于遍歷數組和集合);

6.靜態導入(可以在使用靜方法前不加類名);

7.注釋(采用@前綴,這個基本上是為了簡化J2EE而準備的,在JavaEE5中的EJB3、JPA等中隨處可以看到它的身影)。

在JVM、基本類庫、SDK工具和硬件平臺支持上都有很多的提高,這個JDK版本的出現可以說是Java中的一次飛越。

具體的解釋下:

1.自動包裝和解包(Autoboxing and unboxing)
  代碼示例
  
  往一個ArrayList中加入一個整數,1.5版本以前的版本寫法是:
  
  List list = new ArrayList();
  
  list.add( new Integer( 10 ) );
  
  而在1.5版本中可以寫為:
  
  list.add( 10 );
  
  因為,在1.5版本中,對一個整數進行包裝,使之成為一個Integer對象(即包裝,boxing),然后加入到一個ArrayList中的做法被認為是沒有必要的,反之,解包(unboxing)的做法也是沒有必要的,這樣的代碼只是增加了程序的文本長度而已,所以1.5版本支持了自動包裝和解包操作,對于bool/Boolean,byte /Byte,double/Double,short/Short,int/Integer,long/Long,float/Float的相應包裝/解包操作都進行了支持,從而使代碼變得簡單。
  
  2.更優化的循環語句(The inhanced for loop)
  代碼示例
  
  一個典型的遍歷數組的循環語句,1.5版本以前的寫法是:
  
  for ( Iterator iterator = list.iterator(); iterator.hasNext(); )
  
  {
  
  Integer n = (Integer)iterator.next();
  
  ...
  
  }//for
  
  而在1.5版本中可以寫為:
  
  for ( Integer n : list )
  
  {
  
  ...
  
  }//for
  
  顯然1.5版本的寫法比以前是大大簡化了,但是在需要修改集合,比如刪除其中元素時不能采用這種寫法。之所以Java1.5版本沒有象C#那樣干脆定義一個foreach關鍵詞,主要是因為SUN認為增加一個專門的關鍵詞成本太高了(too costly)。但1.4版本中就曾經增加了assert關鍵詞,1.5版本中也新增加了enum關鍵詞,因此這一解釋恐怕并不那么令人信服。
  
  3.參數可變的方法和printf
  代碼示例
  
  當不能確定一個方法的入口參數的個數時,以往版本的Java中,通常的做法是將多個參數放在一個數組或者對象集合中作為參數來傳遞,1.5版本以前的寫法是:
  
  int sum(Integer[] numbers)
  
  {
  
  int nSum = 0;
  
  for(int i: numbers)
  
  nSum += i;
  
  return nSum;
  
  }
  
  ...
  
  //在別處調用該方法
  
  sum(new Integer[] {12,13,20});
  
  而在1.5版本中可以寫為:
  
  int sum(Integer... numbers)
  
  {
  
  int nSum = 0;
  
  for(int i: numbers)
  
  nSum += i;
  
  return nSum;
  
  }
  
  ...
  
  //在別處調用該方法
  
  sum(12,13,20);
  
  顯然,1.5版本的寫法更為簡易,也更為直觀,尤其是方法的調用語句,不僅簡化很多,而且更符合通常的思維方式,更易于理解。
  
   1.5版本自身就有一個應用該特征的典型例子,即C風格的格式化輸出方法——printf。
  
  代碼示例
  
  輸出一個加法算式,1.5版本以前的寫法是:
  
  int x = 5;
  
  int y = 7;
  
  int nSum = x + y;
  
  System.out.println(x + " + " + y + " = " + nSum);
  
  而在1.5版本中可以寫為:
  
  System.out.printf("%d + %d = %d\n", x, y, nSum);
  
  以上兩種寫法的輸出結構是一樣的,即“5 + 7 = 12”。
  
  這種改變不僅僅是形式上的,printf還可以提供更為靈活、強大的輸出功能,比如限定按照兩位整數的形式輸出,可以寫為 “System.out.printf("%02d + %02d = %02d\n", x, y, nSum);”,輸出結果將是“05 + 07 = 12”。
  
  4.枚舉
  代碼示例
  
  構建一個表示色彩的枚舉,并賦值,在1.5版本中可以寫為:
  

<PRE class=java name="code">  public enum MyColor{ Red, Yellow, Blue }      MyColor color = MyColor.Red;      for ( MyColor mycolor : MyColor.values() )      System.out.println( mycolor );</PRE>


  以往的Java版本中沒有enum關鍵詞,1.5版本中終于加入了進來,這確實是一個令人高興的改進。此外,enum還提供了一個名為values()的靜態方法,用以返回枚舉的所有值的集合。所以,以上程序的輸出結果是把“Red”、“Yellow”、“Blue”分行輸出。
  
  而 enum提供的靜態方法valueOf()則將以字符串的形式返回某一個具體枚舉元素的值,比如“MyColor.valueOf(“Red”)”會返回 “Color.Red”。靜態方法name()則返回某一個具體枚舉元素的名字,比如“MyColor.Red.name()”會返回“Red”。類似的方法還有不少。此外,enum自身還可以有構造方法。
  
  5.靜態引用
  代碼示例
  
  當我們要獲取一個隨即數時,1.5版本以前的寫法是:
  
  import java.lang.Math; //程序開頭處
  
  ...
  
  double x = Math.random();
  
  而在1.5版本中可以寫為:
  
  import static java.lang.Math.random; //程序開頭處
  
  …
  
  double x = random();
  
  靜態引用使我們可以象調用本地方法一樣調用一個引入的方法,當我們需要引入同一個類的多個方法時,只需寫為“import static java.lang.Math.*”即可。這樣的引用方式對于枚舉也同樣有效。

JDK1.6

簡化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與系統管理

管理系統的構架
圖 1. 管理系統構架

 

上圖分析了管理系統的基本構架模式。其中 Agent / SubAgent 起到的就是翻譯的作用:把 IT 資源報告的消息以管理系統能理解的方式傳送出去。

也許讀者有會問,為什么需要 Agent 和 SubAgent 兩層體系呢?這里有兩個現實的原因:

管理系統一般是一個中央控制的控制軟件,而 SubAgent 直接監控一些資源,往往和這些資源分布在同一物理位置。當這些 SubAgent 把狀態信息傳輸到管理系統或者傳達管理系統的控制指令的時候,需要提供一些網絡傳輸的功能。

   1. 管理系統的消息是有一定規范的,消息的翻譯本身是件復雜而枯燥的事情。

一般來說,管理系統會將同一物理分布或者功能類似的 SubAgent 分組成一組,由一個共用的 Agent 加以管理。在這個 Agent 里封裝了 1 和 2 的功能。

JMX 和管理系統

JMX 既是 Java 管理系統的一個標準,一個規范,也是一個接口,一個框架。圖 2 展示了 JMX 的基本架構。
圖 2. JMX 構架和其它的資源系統一樣,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 個步驟:

   1. 分析 JSP 代碼;
   2. 生成 Java 代碼;
   3. 將 Java 代碼寫入存儲器;
   4. 啟動另外一個進程并運行編譯器編譯 Java 代碼;
   5. 將類文件寫入存儲器;
   6. 服務器讀入類文件并運行;

     但如果采用運行時編譯,可以同時簡化步驟 4 和 5,節約新進程的開銷和寫入存儲器的輸出開銷,提高系統效率。實際上,在 JDK 5 中,Sun 也提供了調用編譯器的編程接口。然而不同的是,老版本的編程接口并不是標準 API 的一部分,而是作為 Sun 的專有實現提供的,而新版則帶來了標準化的優點。
     新 API 的第二個新特性是可以編譯抽象文件,理論上是任何形式的對象 —— 只要該對象實現了特定的接口。有了這個特性,上述例子中的步驟 3 也可以省略。整個 JSP 的編譯運行在一個進程中完成,同時消除額外的輸入輸出操作。
     第三個新特性是可以收集編譯時的診斷信息。作為對前兩個新特性的補充,它可以使開發人員輕松的輸出必要的編譯錯誤或者是警告信息,從而省去了很多重定向的麻煩

一些有趣的新特性:

1 本地行為 java.awt.Desktop
比如用默認程序打開文件,用默認瀏覽器打開url,再也不用那個browserlauncher那么費勁

Desktop desk=Desktop.getDesktop();
desk.browse(new URI("
http://www.google.com/"));
desk.open(file)
desk.print(file)

2 console下密碼輸入 java.io.Console
再也不用自己寫線程去刪echo字符了
Console console = System.console();
char password[] = console.readPassword("Enter password: ");

3 獲取磁盤空間大小 java.io.File的新方法

<PRE class=java name="code">File roots[] = File.listRoots(); for (File root : roots) { System.out.println(root.getPath()+":"+root.getUsableSpace() +"/"+root.getTotalSpace()); }</PRE>


 

4 專利過期,可以提供合法的lzw的gif encoder了
ImageIO.write(input, "GIF", outputFile);

5 JAXB2.0 增加了java-to-xml schema,完成java bean,xml間轉換非常容易

6 xml數字簽名 javax.xml.crypto,記得以前似乎只有ibm有個類庫實現了

7 編譯器,以前是com.sun.tools.javac,現在是javax.tools.JavaCompiler
有人寫了完全在內存里的生成源文件,編譯,反射運行的過程,比較好玩。

8 腳本引擎,javax.script,內嵌的是Mozilla Rhino1.6r2 支持ECMAScript1.6

</DIV>

 本文由用戶 xyang81 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!