J2SE 1.5 in a Nutshell 中文版
發(fā)表時間:2024-02-09 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]Java2平臺標(biāo)準(zhǔn)版(J2SE)1.5版本(代號"Tiger")是對Java平臺和語言的下一個重要修改;目前1.5版本的J2SE包含了15個JSR的請求,相應(yīng)的JCP導(dǎo)致了將近100個顯著的修改.看到這個版本帶來了這么多激動人心的變動,你可能想知道你應(yīng)該從哪里開始.和以往的發(fā)布...
Java2平臺標(biāo)準(zhǔn)版(J2SE)1.5版本(代號"Tiger")是對Java平臺和語言的下一個重要修改;目前1.5版本的J2SE包含了15個JSR的請求,相應(yīng)的JCP導(dǎo)致了將近100個顯著的修改.
看到這個版本帶來了這么多激動人心的變動,你可能想知道你應(yīng)該從哪里開始.和以往的發(fā)布一樣,所有的改動都會有一個清晰的列表保存在"Release notes guide".這篇來自J2SE開發(fā)團隊的文章將帶領(lǐng)你巡視主要的變動,使得你可以在深入API文檔之前快速的把握J(rèn)2SE 1.5能提供什么.
J2SE 1.5版本將關(guān)注在下面幾個關(guān)鍵的主題:
簡易的開發(fā) Ease of Development
可擴展性和性能 Scalability and Performance
監(jiān)視和管理能力 Monitoring and Manageability
桌面客戶端 Desktop Client
還有一些特性也很重要,但是和這些主題不相關(guān),所以他們被列在了文末:
其他的特性 Miscellaneous Features
簡易開發(fā) Ease of Development
你可能已經(jīng)看到了一些能使得開發(fā)變得更加簡易的Java語言上新特性的報告.這些特性包括了泛型類別,元數(shù)據(jù),自動裝箱,一個增強的for循環(huán),枚舉類型,靜態(tài)引入,C語言風(fēng)格的輸入輸出,變量參數(shù),并行工具和一個簡單化了的RMI接口生成.
JSR 201包含了上述語言特性中的4個:增強的for循環(huán),枚舉類型,靜態(tài)導(dǎo)入和自動裝箱;JSR 175 說明了元數(shù)據(jù)機能;而JSR 14則詳細(xì)說明了泛型類別.
在javac編譯器中使用的默認(rèn)的語言是J2SE1.4.這就意味著如果你想使用任何的這些新語言特性必須在編譯的時候在javac的命令行上添加一個參數(shù) -source 1.5.(譯者按:這也是目前很多的開發(fā)人員下載了這個版本以后發(fā)現(xiàn)無法使用這些新特性的原因.)
元數(shù)據(jù) Metadata
J2SE 1.5 中的元數(shù)據(jù)特性提供了一個連接附加數(shù)據(jù)到Java Class,Interface,Method和Field中的能力.這些附加的數(shù)據(jù)或者注解能被javac編譯器或者其他的工具識別,并且可以根據(jù)配置保存在class文件中,并且能在運行時通過Java的reflection API來發(fā)現(xiàn).
給Java平臺添加元數(shù)據(jù)的一個主要原因是似的開發(fā)和運行工具能得到一個基礎(chǔ)框架,使得可以減少在編碼和發(fā)布的時候需要的額外的努力.一個工具能使用這些元數(shù)據(jù)信息來產(chǎn)生一些額外的代碼或者在調(diào)試的時候提供額外的信息.
代替元數(shù)據(jù)工具,下面的范例代碼創(chuàng)建了一個智能調(diào)試的元數(shù)據(jù)注解.這個注解將在隨后的調(diào)試中簡單的顯示出來.我們可以看到大部分的元數(shù)據(jù)標(biāo)簽組成了一個標(biāo)準(zhǔn)的,固定的集合.
import java.lang.annotation.*;
import java.lang.reflect.*;
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @interface debug {
boolean devbuild() default false;
int counter();
}
public class MetaTest {
final boolean production=true;
@debug(devbuild=production,counter=1) public void testMethod() {
}
public static void main(String[] args) {
MetaTest mt = new MetaTest();
try {
Annotation[] a = mt.getClass().getMethod("testMethod").getAnnotations();
for (int i=0; i<a.length ; i++) {
System.out.println("a["+i+"]="+a[i]+" ");
}
} catch(NoSuchMethodException e) {
System.out.println(e);
}
}
}
有了元數(shù)據(jù)處理工具,很多重復(fù)的編碼步驟可以減少到一個簡潔的元數(shù)據(jù)標(biāo)簽中.比如訪問JAX-RPC的時候需要的遠(yuǎn)程接口服務(wù)實現(xiàn)可以按照下面這樣實現(xiàn):
以前 Before
public interface PingIF extends Remote {
public void ping() throws RemoteException;
}
public class Ping implements PingIF {
public void ping() {
}
}
用了元數(shù)據(jù)后 After
public class Ping {
public @remote void ping() {
}
}
泛型類型 Generic Types
泛型類別在Java社區(qū)中已經(jīng)期待已久,現(xiàn)在泛型成了J2SE 1.5 的一部分.第一顯著的能看到泛型類別的地方是集合的API中.集合的API提供了一些通用功能例如:LinkedLists,ArrayLists和HashMaps等等這些能用于多種類型的集合類型.下面的例子使用J2SE 1.4.2的類庫,并且使用默認(rèn)的javac編譯模式.
ArrayList list = new ArrayList();
list.add(0, new Integer(42));
int total = ((Integer)list.get(0)).intValue();
上面例子中最后一行一個強制轉(zhuǎn)型到Integer類型是泛型類別想解決的強制轉(zhuǎn)型問題.這個問題就是J2SE 1.4.2的集合API是用Object來存儲集合對象的,這就意味這集合不能在編譯的時候偵測到類型不符這樣的問題.一個典型的問題就是會在運行時拋出ClassCastException.
下面是運用了泛型類別后改寫的上面的范例:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, new Integer(42));
int total = list.get(0).intValue();
這些泛型化的集合API強制在編譯的時候用<>來指定集合中存儲的數(shù)據(jù)類型.用了泛型以后就不再有轉(zhuǎn)型的需要了,而且在這個例子中如果試圖添加一個String類型的變量到這個聲明為Integer的集合中去將會導(dǎo)致一個編譯錯誤.
泛型類別使得API的設(shè)計者能提供通用的機能,并且能運用于多種數(shù)據(jù)類型,并且能在編譯的時候就檢查類型的安全性.
泛型的API要稍微復(fù)雜一些.建議可以從java.util.Collection包的源代碼和API的使用指南開始看起.
基本類型的自動裝箱和自動拆箱 Autoboxing and Auto-unboxing of Primitive Types
在基本類型和對應(yīng)的對象副本之間的轉(zhuǎn)化,例如從基本型int,boolean到他們相對應(yīng)的對象副本Integer和Boolean的轉(zhuǎn)化會需要一些根本不必要的代碼,特別是一些只在在集合API中會出現(xiàn)的轉(zhuǎn)化操作.
對Java基本類型的自動裝箱和自動拆箱使得代碼能更加簡潔易懂.下面的這個例子示范了將一個int類型的數(shù)據(jù)存儲到一個ArrayList中,并且再取出來.J2SE 1.5使得在int和Integer對象之間的轉(zhuǎn)化能自動進行.
以前 Before
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, new Integer(42));
int total = (list.get(0)).intValue();
使用自動裝箱和自動拆箱后 After
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, 42);
int total = list.get(0);
增強的for循環(huán) Enhanced for loop
在集合的API中,Iterator類別是使用率非常高的一個class.他提供了一種順序訪問集合元素的能力.新增強的for循環(huán)能在簡單的順序訪問集合元素的時候代替Iterator.編譯器會自動產(chǎn)生必要的帶類型安全,并且不需要轉(zhuǎn)型操作的循環(huán)代碼.
以前 Before
ArrayList<Integer> list = new ArrayList<Integer>();
for (Iterator i = list.iterator(); i.hasNext();) {
Integer value=(Integer)i.next();
}
使用增強for循環(huán)以后 After
ArrayList<Integer> list = new ArrayList<Integer>();
for (Integer i : list) { ... }
枚舉化的類型 Enumerated types
這種類型和使用static final的常量相比提供了枚舉化的類型.如果你曾經(jīng)在你的代碼中用enum這樣的變量名,當(dāng)你用javac -source 1.5進行編譯的時候?qū)⑿枰{(diào)整一下你的代碼,因為J2SE 1.5 引入了一個新的關(guān)鍵字enum.
public enum StopLight { red, amber, green };
靜態(tài)引入 Static Import
靜態(tài)引入的特性是用"import static"這樣的語句使得你能不輸入類名就可以直接使用一個類中的靜態(tài)常量.比如我們經(jīng)常在添加一個控件的時候用的BorderLayout.CENTER,使用了靜態(tài)引入后,你只需要簡單的調(diào)用CENTER就可以了.
import static java.awt.BorderLayout.*;
getContentPane().add(new JPanel(), CENTER);
格式化的輸出 Formatted Output
開發(fā)人員現(xiàn)在可以使用類似C語言中的printf這樣的功能來產(chǎn)生格式化的輸出.現(xiàn)在可以象C語言中一樣使用printf,而且語言上基本沒有變化,一般可以不變,有些格式可能需要稍微的變化一下.
大部分的通用C printf格式都可以使用,同時一些Java的類例如Date和BigInteger也擁有了格式化規(guī)則.可以在java.util.Formatter類中找到更多的信息.
System.out.printf("name count\n");
System.out.printf("%s %5d\n", user,total);
格式化的輸入 Formatted Input
這個Scanner API提供了基本的讀入數(shù)據(jù)的功能,例如從控制臺上或者其他任何的數(shù)據(jù)流中讀入數(shù)據(jù)的功能.下面的范例從標(biāo)準(zhǔn)輸入中讀入了一個字符串并且希望字符串隨后是一個int值.
Scanner中的方法例如next和nextInt會在沒有數(shù)據(jù)的時候自動失效.如果你需要處理一個非常復(fù)雜的輸入,那么還可以使用java.util.Formatter類中的模式匹配算法.
Scanner s=Scanner.create(System.in);
String param= s.next();
int value=s.nextInt();
s.close();
不定參數(shù) Varargs
不定參數(shù)(varargs)機能允許在一個方法中傳入多個不定數(shù)量的參數(shù).而這只是簡單需要用...來表示某個方法接受不定參數(shù).而這正是在printf方法中接受任意數(shù)量個參數(shù)的基礎(chǔ).
void argtest(Object ... args) {
for (int i=0;i <args.length; i++) {
}
}
argtest("test", "data");
并行工具 Concurrency Utilities
并行工具包是由Doug Lea在帶領(lǐng)的JSR-166中提出要添加到J2SE 1.5中去的,這是一個非常流行的并行工具包.他提供了功能強大的,高層次的線程構(gòu)造器,包含了執(zhí)行器,例如一個線程任務(wù)框架,線程安全的隊列,計時器,鎖(包含了原子級別的鎖)和其他一些同步的基本類型.
其中的鎖是一個眾所周知的信號.一個信號能在現(xiàn)在使用wait的地方使用,他通常用來限制對某一代碼塊的訪問.信號量將更加靈活并且能允許多個并行的線程來訪問,也允許你在得到一個鎖之前可以測試這個鎖.下面的代碼示范了使用一個信號量,也被稱為是二分信號.更多的信息請參看java.util.concurrent包.
final private Semaphore s= new Semaphore(1, true);
s.acquireUninterruptibly(); //for non-blocking version use s.acquire()
balance=balance+10; //protected value
s.release(); //return semaphore token
rmi編譯器--rmic rmic -- the rmi Compiler
你可能再也不需要使用rmic來產(chǎn)生那些遠(yuǎn)程的接口樁.動態(tài)代理的方法說明了通常由樁提供的信息可以在在運行時被發(fā)現(xiàn).更多的信息請參看RMI release notes.
可擴展性和性能 Scalability and Performance
J2SE 1.5版本的發(fā)布保證改進可擴展性和性能,尤其是在啟動時和內(nèi)存印記的時候,使得能更加簡單的發(fā)布一個應(yīng)用程序并且運行的非?.
一個非常顯著的更新是介紹類數(shù)據(jù)在Hotspot JVM中的分享.這個技術(shù)不僅在多個運行的JVM之間分享只讀數(shù)據(jù),并且改進了啟動時間,使得看起來這些類都象JVM的核心的類一樣是預(yù)先裝載的.
性能的人體工程學(xué)是J2SE 1.5中的一個新特性,這意味這如果你在過去的J2SE版本中使用過特殊的JVM運行時選項來提升性能,這將值得你在J2SE的JVM中沒有JVM運行時沒有參數(shù)或者少量參數(shù)的情況下重新驗證你的性能,因為J2SE的性能已經(jīng)提升了很多了.
監(jiān)視和管理 Monitoring and Manageability
監(jiān)視和管理是Java平臺上RAS(Reliability, Availability, Serviceability)的一個關(guān)鍵組件.
JVM的監(jiān)視和管理API(JSR-174)詳細(xì)說明了一套非常容易理解的JVM內(nèi)部機制,這些內(nèi)部機制在一個運行的JVM上被監(jiān)視到.這個信息是通過JMX(JSR-003)消息Bean來訪問的,并且能通過JMX的遠(yuǎn)程接口(JSR-160)來遠(yuǎn)程的訪問或者通過業(yè)界標(biāo)準(zhǔn)的SNMP工具來訪問.
最重要的特性之一是一個底層的內(nèi)存探測器 .當(dāng)入口(threshold)交叉的時候,JMX MBeans能通知那些被注冊過的監(jiān)聽器,詳細(xì)內(nèi)容請參看javax.management 和 java.lang.management
為了能直觀的看到使用這些 API是多么的簡單,下面就有一個報告在Hotspot JVM中內(nèi)存堆棧詳細(xì)使用情況的范例.
import java.lang.management.*;
import java.util.*;
import javax.management.*;
public class MemTest {
public static void main(String args[]) {
List pools =ManagementFactory.getMemoryPoolMBeans();
for(ListIterator i = pools.listIterator(); i.hasNext();) {
MemoryPoolMBean p = (MemoryPoolMBean) i.next();
System.out.println("Memory type="+p.getType()+" Memory usage="+p.getUsage());
}
}
}
新的JVM 整形API(JSR-163) New JVM profiling API (JSR-163)
這次的發(fā)布還包含了一個非常強勁的本地整形API叫做JVMTI.這套API在JSR163中已經(jīng)詳細(xì)說明過,并且是針對改進整形接口的需求而來的.不管怎么樣,JVMTI想關(guān)注所有本地進程內(nèi)的工具訪問.除了整形以外,還包括了監(jiān)視,調(diào)試和一個可能將會支持多種代碼分析的工具.
這些API的實現(xiàn)包括了一套bytecode測試設(shè)備的機制,JPLIS(Java Programming Language Instrumentation Services -Java編程語言測試設(shè)備服務(wù)).這將允許分析工具在必要的時候來添加額外的整形.這個技術(shù)的優(yōu)點是他允許更多的焦點分析并且限制JVM中跑的不同的整形工具之間的沖突.這套測試設(shè)備甚至能在運行時自動的生成,就如同class的裝載時候和預(yù)處理的class文件一樣.
下面的范例建立了一套能從磁盤上裝載一個修改過 class文件的測試設(shè)備勾子.要運行下面的測試,在啟動JRE的時候,用java -javaagent:myBCI BCITest的方式.
//File myBCI.java
import java.lang.instrument.Instrumentation;
public class myBCI {
private static Instrumentation instCopy;
public static void premain(String options, Instrumentation inst) {
instCopy = inst;
}
public static Instrumentation getInstrumentation() {
return instCopy;
}
}
//File BCITest.java
import java.nio.*;
import java.io.*;
import java.nio.channels.*;
import java.lang.instrument.*;
public class BCITest {
public static void main (String[] args) {
try {
OriginalClass mc = new OriginalClass();
mc.message();
FileChannel fc=new FileInputStream(new File("modified"+File.separator+"OriginalClass.class")).getChannel();
ByteBuffer buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, (int)fc.size());
byte[] classBuffer = new byte[buf.capacity()];
buf.get(classBuffer, 0, classBuffer.length);
myBCI.getInstrumentation().redefineClasses(new ClassDefinition[] {new ClassDefinition(mc.getClass(), classBuffer)});
mc.message();
}catch (Exception e){}
}
}
//OriginalClass.java
//Compile in current directory
//Copy source to modified directory,change message and recompile
public class OriginalClass {
public void message() {
System.out.println("OriginalClass");
}
}
改進的診斷能力 Improved Diagnostic Ability
在沒有控制臺窗口的時候生成堆棧跟蹤是無用的.現(xiàn)在有兩個新的API,getStackTrace和Thread.getAllStackTraces提供了使得這些信息可編程的能力.
StackTraceElement e[]=Thread.currentThread().getStackTrace();
for (int i=0; i <e.length; i++) {
System.out.println(e[i]);
}
System.out.println("\n"+Thread.getAllStackTraces());
Hotspot JVM包括了一個致命錯誤的處理機制,使得在JVM放棄的時候運行一個用戶支持的腳本或者一段程序.一個調(diào)試工具也能用Hotspot JVM的可服務(wù)代理連接器連接到這個已經(jīng)掛起的JVM或者那些核心文件.
-XX:OnError="command"
-XX:OnError="pmap %p"
-XX:OnError="gdb %p"
optional %p used as process id
桌面客戶端 Desktop Client
Java的桌面客戶端仍然是作為Java平臺的一個關(guān)鍵組件,同時這個組件在J2SE 1.5中也有了很大的改進.
在這次的Beta發(fā)布中包含了一些早先對啟動時間和內(nèi)存印記的改進.不僅變的快速了,而且Swing的工具中還帶了一個嶄新的界面風(fēng)格叫做Ocean.
在J2SE 1.4.2的基礎(chǔ)上,對GTK可更換的Look and Feel以及Window XP的Look and Feel有了進一步的改進.
Windows XP
Click to Enlarge
Linux/Redhat
Click to Enlarge
Linux和Solaris的用戶只要有最新的OpenGL驅(qū)動和顯卡,就能讓Java2D得到本地的硬件加速,可以非常顯著的改善顯示效果,只需要在啟動的時候添加下面這樣的參數(shù)就可以了:
java -Dsun.java2d.opengl=true -jar Java2D.
同時在Linux的發(fā)布版本中還包含了一個快速的X11工具包,叫做XAWT,默認(rèn)就是使用這個工具包的.如果你需要使用過去的motif的工具包,你需要在啟動的時候添加如下的系統(tǒng)參數(shù):
java -Dawt.toolkit=sun.awt.motif.MToolkit -jar Notepad.jar
(X11的工具包叫做sun.awt.X11.XToolkit)
同時X11的工具包還使用了xDnD的協(xié)議,所以你可以在Java和其他應(yīng)用程序之間,比如StarOffice或者Mozilla,拖拽簡單的組件.
其他的一些新特性 Miscellaneous Features
核心支持XML Core XML Support
J2SE 1.5 介紹了一些對核心XML平臺的修改,包括了XML 1.1,Namespace,XML Schema.還有SAX 2.0.1,XSLT和快速的XLSTC編譯器,還有對DOM level 3的支持.
除了對核心XML的支持特性以外,JWSDP(Java Web Services Developer Pack)將會發(fā)布最新的Web services標(biāo)準(zhǔn):JAX-RPC & SAAJ(WSDL/SOAP),JAXB,XML加密以及數(shù)字簽名和注冊用的JAXR.
補充的字符支持 Supplementary Character Support
32位的補充字符支持是被非常小心的添加到了J2SE 1.5中來的,他是作為過渡到Unicode 4.0支持的一個部分.補充的字符被編碼成特殊的一對對UTF16的值來生成一個個不同的字符,或者從代碼的角度來看,被代替的一對值是由一個高位的UTF16值緊隨一個低位的UTF16值,而這個高位和低位的值都是從一個特殊的UTF16值范圍內(nèi)取出來的.
通俗點說,當(dāng)使用一個String或者字符序列的時候,核心的API庫會透明的為你處理這些補充的字符.但是java的char類型數(shù)據(jù)仍然是16位的,少數(shù)使用char作為參數(shù)的方法現(xiàn)在有了相應(yīng)的能接受一個int值的方法,這些方法能表現(xiàn)新的這些大值.特別是Character類,添加了一些象下面代碼中的方法來找回當(dāng)前的字符和隨后的字符來支持這些補充的字符:
String u="\uD840\uDC08";
System.out.println(u+"+ "+u.length());
System.out.println(Character.isHighSurrogate(u.charAt(0)));
System.out.println((int)u.charAt(1));
System.out.println((int)u.codePointAt(0));
詳細(xì)信息請參考Character類中的Unicode部分.
JDBC的行集 JDBC RowSets
對JDBC 行集的支持上有兩個更新.一個是CachedRowSet,包含了保存在內(nèi)存中從數(shù)據(jù)庫中取回來的行集合.并且他們是未連接的,這就意味著對這些行集的更新可以在過一段時間后同步到數(shù)據(jù)庫中.
另外一個是WebRowSet,是一種用XML的方式來傳遞數(shù)據(jù)庫中的行數(shù)據(jù)信息.