轉(zhuǎn)載:jdk5.0新特性
以下是網(wǎng)上摘錄的: JDK5.0的新特性(2005-2006)
“JDK1.5”(開發(fā)代號(hào)猛虎)的一個(gè)重要主題就是通過(guò)新增一些特性來(lái)簡(jiǎn)化開發(fā),
這些特性包括泛型,for-each 循環(huán),自動(dòng)裝包/拆包,枚舉,可變參數(shù), 靜態(tài)導(dǎo)入
C 風(fēng)格的格式化 I/O、、并發(fā)實(shí)用程序以及更簡(jiǎn)單的 RMI 接口生成。
這些特性包括泛型,for-each 循環(huán),自動(dòng)裝包/拆包,枚舉,可變參數(shù), 靜態(tài)導(dǎo)入
C 風(fēng)格的格式化 I/O、、并發(fā)實(shí)用程序以及更簡(jiǎn)單的 RMI 接口生成。
JSR 201 包括如下四個(gè)語(yǔ)言變化:增強(qiáng)的 for 循環(huán)、枚舉類型、靜態(tài)導(dǎo)入和 autoboxing;JSR 175 指定了新的元數(shù)據(jù)功能,而 JSR 14 則詳細(xì)說(shuō)明了泛型。
javac 編譯器執(zhí)行的默認(rèn)語(yǔ)言規(guī)范是版本 1.4。這意味著要利用以下語(yǔ)言變化的任何好處,需要向 javac 命令傳遞參數(shù) -source 1.5。
使用這些特性有助于我們編寫更加清晰,精悍,安全的代碼。
下面我們簡(jiǎn)單介紹一下這些新特性。
1.泛型(Generic)
C++通過(guò)模板技術(shù)可以指定集合的元素類型,而Java在1.5之前一直沒(méi)有相對(duì)應(yīng)的功
能。一個(gè)集合可以放任何類型的對(duì)象,相應(yīng)地從集合里面拿對(duì)象的時(shí)候我們也不得不對(duì)
他們進(jìn)行強(qiáng)制得類型轉(zhuǎn)換。猛虎引入了泛型,它允許指定集合里元素的類型,這樣你可
以得到強(qiáng)類型在編譯時(shí)刻進(jìn)行類型檢查的好處。
能。一個(gè)集合可以放任何類型的對(duì)象,相應(yīng)地從集合里面拿對(duì)象的時(shí)候我們也不得不對(duì)
他們進(jìn)行強(qiáng)制得類型轉(zhuǎn)換。猛虎引入了泛型,它允許指定集合里元素的類型,這樣你可
以得到強(qiáng)類型在編譯時(shí)刻進(jìn)行類型檢查的好處。
Collection c = new ArrayList();
c.add(new Date());
c.add(new Date());
編譯器會(huì)給出一個(gè)錯(cuò)誤:
add(java.lang.String) in java.util.Collection cannot be applied to
(java.util.Date)
(java.util.Date)
2.For-Each循環(huán)
For-Each循環(huán)得加入簡(jiǎn)化了集合的遍歷。假設(shè)我們要遍歷一個(gè)集合對(duì)其中的元素進(jìn)
行一些處理。典型的代碼為:
行一些處理。典型的代碼為:
void processAll(Collection c){
for(Iterator i=c.iterator(); i.hasNext();){
MyClass myObject = (MyClass)i.next();
myObject.process();
}
}
for(Iterator i=c.iterator(); i.hasNext();){
MyClass myObject = (MyClass)i.next();
myObject.process();
}
}
使用For-Each循環(huán),我們可以把代碼改寫成:
void processAll(Collection c){
for (MyClass myObject :c)
myObject.process();
}
for (MyClass myObject :c)
myObject.process();
}
這段代碼要比上面清晰許多,并且避免了強(qiáng)制類型轉(zhuǎn)換。
3.自動(dòng)裝包/拆包(Autoboxing/unboxing)
自動(dòng)裝包/拆包大大方便了基本類型數(shù)據(jù)和它們包裝類地使用。
自動(dòng)裝包:基本類型自動(dòng)轉(zhuǎn)為包裝類.(int >> Integer)
自動(dòng)拆包:包裝類自動(dòng)轉(zhuǎn)為基本類型.(Integer >> int)
在JDK1.5之前,我們總是對(duì)集合不能存放基本類型而耿耿于懷,現(xiàn)在自動(dòng)轉(zhuǎn)換機(jī)制
解決了我們的問(wèn)題。
解決了我們的問(wèn)題。
int a = 3;
Collection c = new ArrayList();
c.add(a);//自動(dòng)轉(zhuǎn)換成Integer.
Collection c = new ArrayList();
c.add(a);//自動(dòng)轉(zhuǎn)換成Integer.
Integer b = new Integer(2);
c.add(b + 2);
c.add(b + 2);
這里Integer先自動(dòng)轉(zhuǎn)換為int進(jìn)行加法運(yùn)算,然后int再次轉(zhuǎn)換為Integer.
4.枚舉(Enums)
JDK1.5加入了一個(gè)全新類型的“類”-枚舉類型。為此JDK1.5引入了一個(gè)新關(guān)鍵字
enmu. 我們可以這樣來(lái)定義一個(gè)枚舉類型。
public enum Color
{
Red,
White,
Blue
}
enmu. 我們可以這樣來(lái)定義一個(gè)枚舉類型。
public enum Color
{
Red,
White,
Blue
}
然后可以這樣來(lái)使用Color myColor = Color.Red.
枚舉類型還提供了兩個(gè)有用的靜態(tài)方法values()和valueOf(). 我們可以很方便地
使用它們,例如
使用它們,例如
for (Color c : Color.values())
System.out.println(c);
System.out.println(c);
5.可變參數(shù)(Varargs)
可變參數(shù)使程序員可以聲明一個(gè)接受可變數(shù)目參數(shù)的方法。注意,可變參數(shù)必須是
函數(shù)聲明中的最后一個(gè)參數(shù)。假設(shè)我們要寫一個(gè)簡(jiǎn)單的方法打印一些對(duì)象,
函數(shù)聲明中的最后一個(gè)參數(shù)。假設(shè)我們要寫一個(gè)簡(jiǎn)單的方法打印一些對(duì)象,
util.write(obj1);
util.write(obj1,obj2);
util.write(obj1,obj2,obj3);
…
util.write(obj1,obj2);
util.write(obj1,obj2,obj3);
…
在JDK1.5之前,我們可以用重載來(lái)實(shí)現(xiàn),但是這樣就需要寫很多的重載函數(shù),顯得
不是很有效。如果使用可變參數(shù)的話我們只需要一個(gè)函數(shù)就行了
不是很有效。如果使用可變參數(shù)的話我們只需要一個(gè)函數(shù)就行了
public void write(Object... objs) {
for (Object obj: objs)
System.out.println(obj);
}
for (Object obj: objs)
System.out.println(obj);
}
在引入可變參數(shù)以后,Java的反射包也更加方便使用了。對(duì)于
c.getMethod("test", new Object[0]).invoke(c.newInstance(), new
Object[0])),現(xiàn)在我們可以這樣寫了
c.getMethod("test").invoke(c.newInstance()),這樣的代碼比原來(lái)清楚了很多。
c.getMethod("test", new Object[0]).invoke(c.newInstance(), new
Object[0])),現(xiàn)在我們可以這樣寫了
c.getMethod("test").invoke(c.newInstance()),這樣的代碼比原來(lái)清楚了很多。
6.靜態(tài)導(dǎo)入(Static Imports)
要使用用靜態(tài)成員(方法和變量)我們必須給出提供這個(gè)方法的類。使用靜態(tài)導(dǎo)入
可以使被導(dǎo)入類的所有靜態(tài)變量和靜態(tài)方法在當(dāng)前類直接可見,使用這些靜態(tài)成員無(wú)需
再給出他們的類名。
可以使被導(dǎo)入類的所有靜態(tài)變量和靜態(tài)方法在當(dāng)前類直接可見,使用這些靜態(tài)成員無(wú)需
再給出他們的類名。
import static java.lang.Math.*;
…….
r = sin(PI * 2); //無(wú)需再寫r = Math.sin(Math.PI);
…….
r = sin(PI * 2); //無(wú)需再寫r = Math.sin(Math.PI);
不過(guò),過(guò)度使用這個(gè)特性也會(huì)一定程度上降低代碼地可讀性。
元數(shù)據(jù)
J2SE 1.5 中的元數(shù)據(jù)特性提供這樣的能力,即向 Java 類、接口、方法和字段關(guān)聯(lián)附加的數(shù)據(jù)。這些附加的數(shù)據(jù)或者注釋,可以被 javac 編譯器或其他工具讀取,并且根據(jù)配置不同,可以被保存在類文件中,也可以在運(yùn)行時(shí)使用 Java 反射 API 被發(fā)現(xiàn)。
J2SE 1.5 中的元數(shù)據(jù)特性提供這樣的能力,即向 Java 類、接口、方法和字段關(guān)聯(lián)附加的數(shù)據(jù)。這些附加的數(shù)據(jù)或者注釋,可以被 javac 編譯器或其他工具讀取,并且根據(jù)配置不同,可以被保存在類文件中,也可以在運(yùn)行時(shí)使用 Java 反射 API 被發(fā)現(xiàn)。
向 Java 平臺(tái)增加元數(shù)據(jù)的一個(gè)主要原因是,使得開發(fā)工具和運(yùn)行工具有一個(gè)通用的基礎(chǔ)結(jié)構(gòu),以減少開發(fā)和部署所需的成本。工具可以使用元數(shù)據(jù)信息生成附加的源代碼,或者在調(diào)試時(shí)提供附加信息。
下面的例子用元數(shù)據(jù)工具創(chuàng)建了一個(gè)調(diào)試元數(shù)據(jù)注釋,這些元數(shù)據(jù)注釋然后又簡(jiǎn)單地在運(yùn)行時(shí)顯示出來(lái)。可以想像,大部分的元數(shù)據(jù)標(biāo)簽形成一個(gè)標(biāo)準(zhǔn),即一個(gè)良好規(guī)范的集合。
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;
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+" ");
}
} catch(NoSuchMethodException e) {
System.out.println(e);
}
}
}
}
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+" ");
}
} catch(NoSuchMethodException e) {
System.out.println(e);
}
}
}
利用一個(gè)元數(shù)據(jù)處理工具,許多重復(fù)的代碼編寫步驟可以減少成一個(gè)簡(jiǎn)練的元數(shù)據(jù)標(biāo)簽。例如,訪問(wèn)某個(gè) JAX-RPC 服務(wù)實(shí)現(xiàn)時(shí)所需的遠(yuǎn)程接口可以實(shí)現(xiàn)為:
原來(lái)(J2SE 1.5 以前版本):
public interface PingIF extends Remote {
public void ping() throws RemoteException;
}
public void ping() throws RemoteException;
}
public class Ping implements PingIF {
public void ping() {
}
}
public void ping() {
}
}
現(xiàn)在:
public class Ping {
public @remote void ping() {
}
}
public @remote void ping() {
}
}
二、元數(shù)據(jù)(注解)
這是JDK5.0學(xué)XDoclt的,有了注解,以后我們可以不必寫接口,EJB寫起來(lái)會(huì)方便很多。EJB3.0要精簡(jiǎn)寫法,注解要占一些功勞。
介紹一個(gè)常用的注解:@Override,示例如下:
public class Test extends ATest{
@Override
public void test() {
}
}
在方法前加了這個(gè)注解,就限定死了Test的這個(gè)方法一定要是覆蓋自ATest的方法test,否則就會(huì)報(bào)錯(cuò)。比如你不心把方法test()寫成了tesd(),編譯時(shí)就會(huì)報(bào)錯(cuò)。另一個(gè)要注意的是@Override用于定義覆蓋接口的方法,也就是說(shuō)ATest必須是一個(gè)抽象類、普通類,但不能是接口。
另一個(gè)常見到的注解是@Deprecated,表明該項(xiàng)(類、字段、方法)不再被推薦使用。不過(guò)我們自己一般很少用到這個(gè)注解。
好了,注解只講這兩個(gè)吧,也不必了解太多,知道個(gè)概念,以后用到的時(shí)候再說(shuō)吧。關(guān)于注解,建議看看XDoclt,這是一個(gè)開源小工具,在項(xiàng)目開發(fā)中非常好用。
版權(quán)聲明:可以任意轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原始出處和作者信息及本聲明
作者:
David Flanagan;xml1123
原文地址:
http://www.onjava.com/pub/a/onjava/2005/04/20/javaIAN5.html
中文地址:
http://www.matrix.org.cn/resource/article/43/43830_Java5.html
關(guān)鍵詞: Java5
至今,毫無(wú)疑問(wèn)你已經(jīng)看過(guò)不止一篇網(wǎng)上文章列舉了Java5.0的偉大的語(yǔ)言新特性:泛型,標(biāo)注,枚舉類型,自動(dòng)裝箱,可變參數(shù), for/in循環(huán),甚至靜態(tài)引入。我也認(rèn)為這些是偉大的特性,但是,你已經(jīng)讀過(guò)他們了。因此,在此我將集中于你可能沒(méi)有聽說(shuō)過(guò)的Java5.0的新API特性。
那么,在下面,是我喜歡的Java5.0的五個(gè)新API特性。我已經(jīng)在《果殼中的Java》(《Java in a nut shell》)第五版的第五章中介紹過(guò)他們。并且我也在我的網(wǎng)站中記錄了其中的一些。那些看完本文后的細(xì)心的讀者會(huì)發(fā)現(xiàn)額外的獎(jiǎng)勵(lì)—第六個(gè)特性:很少有人知道的Java5.0支持的新語(yǔ)言語(yǔ)法,當(dāng)然使用者就更少了。我非常喜歡它,因?yàn)樗苄庐悺?br>
Callable 和 Future 接口
我喜歡的第一個(gè)特性發(fā)掘自新的java.util.concurrent包。如它的名字暗示的,這是個(gè)并行編程工具包。在此有很多要探索的,而我要提的第一喜歡的特性是TimeUnit枚舉類型。TimeUnit讓我感興趣的是它包含有用的時(shí)間相關(guān)工具--你通過(guò)一個(gè)枚舉常量來(lái)調(diào)用它們,該常量代表度量時(shí)間的單位。例如:
TimeUnit.MILLISECONDS.sleep(200);
然而,TimeUnit并不是最值得夸獎(jiǎng)的。java.util.concurrent最強(qiáng)大的特性之一是它的任務(wù)-執(zhí)行/線程-池結(jié)構(gòu)。ExecutorService接口提供了執(zhí)行任務(wù)的能力。Executors類定義了工廠方法用于獲取使用線程池的ExecutorService的實(shí)現(xiàn)。這是強(qiáng)大的要素。
我所喜歡的任務(wù)-執(zhí)行框架的部分是它如何表現(xiàn)任務(wù)以及執(zhí)行它的結(jié)果:Callable和Future接口。我們都熟悉用于定義線程的Runnable接口和它的run()方法。Callable像Runnable,但它的方法叫做call(),并且這個(gè)方法可以返回一個(gè)結(jié)果或者拋出一個(gè)異常,而這兩點(diǎn)是Runnable.run()做不到的。
Callable是一個(gè)泛型,并且它的結(jié)果已經(jīng)參數(shù)化。例如,一個(gè)計(jì)算BigInteger的任務(wù),是Callable<BigInteger>,并且它的方法call()被聲明為返回BigInteger。下面是僅有三行代碼的Callable接口:
public interface Callable<V> {
V call() throws Exception;
}
當(dāng)我想要異步執(zhí)行一個(gè)Callable任務(wù),我將它傳遞給ExecutorService的submit()方法。submit()的返回值—這也是我喜歡的部分—是一個(gè)Future對(duì)象:本質(zhì)上是一個(gè)對(duì)將來(lái)某時(shí)刻的結(jié)果的“借條”。如果我準(zhǔn)備使用我的任務(wù)的結(jié)果,我簡(jiǎn)單的調(diào)用Future對(duì)象的get()方法即可。如果任務(wù)的執(zhí)行已完成,那么get()立刻返回結(jié)果。否則,它將阻塞直到結(jié)果可用。如果Callable拋出異常,那么get()方法將該異常包裝為ExecutionException并且拋出它。Future還有方法用來(lái)對(duì)任務(wù)的執(zhí)行進(jìn)行取消和查詢狀態(tài),但是你必須自己查找它們(這些方法)。Future也用了泛型,并且結(jié)果的類型也參數(shù)化了。因此如果我submit()一個(gè)Callable<BigInteger>來(lái)執(zhí)行,我將獲得一個(gè)Future< BigInteger >。
下面是一個(gè)簡(jiǎn)短的例子:
/**
* 這是一個(gè)用來(lái)計(jì)算大素?cái)?shù)的Callable。
*/
public class PrimeSearch implements Callable<BigInteger>
{
static Random prng = new SecureRandom();
int n;
public PrimeSearch(int bitsize) { n = bitsize; }
public BigInteger call() {
return BigInteger.probablePrime(n, prng);
}
}
// 嘗試同時(shí)計(jì)算兩個(gè)素?cái)?shù)
ExecutorService pool = Executors.newFixedThreadPool(2);
Future<BigInteger> p = pool.submit(new PrimeSearch(512));
Future<BigInteger> q = pool.submit(new PrimeSearch(512));
// 將兩個(gè)素?cái)?shù)相乘來(lái)得到一個(gè)合數(shù)
BigInteger product = p.get().multiply(q.get());
可變參數(shù)和自動(dòng)裝箱
我說(shuō)過(guò)我不想談?wù)揓ava5.0的新語(yǔ)言特性,我不會(huì),但是我確實(shí)關(guān)注由于可變參數(shù)和自動(dòng)裝箱才變?yōu)榭赡艿模ɑ蛘弑辉鰪?qiáng)的舊API)新的API。
首先,當(dāng)然,是Java5.0的printf風(fēng)格的文本格式化能力,通過(guò)java.util.Formatter類和類似String.format()的工具方法。這類文本格式化是最常被引用來(lái)支持語(yǔ)言的增加的可變參數(shù)和自動(dòng)裝箱的那種用例。考慮這個(gè):
String s = String.format("%s:%d: %s%n", filename,
lineNumber,
exception.getMessage());
關(guān)于這段代碼沒(méi)有什么特別值得注意的東西。我將它列在這是為了說(shuō)明因?yàn)榭勺儏?shù)和自動(dòng)裝箱所以比下面的例子顯得簡(jiǎn)單:
String s = String.format("%s:%d: %s%n", new Object[] {
filename,
new Integer(lineNumber),
exception.getMessage()});
一、C風(fēng)格格式化輸出
在JDK5.0后,我們這樣寫代碼:
public static void main(String[] args) {
int x = 10;
int y = 20;
int sum = x + y;
System.out.printf("%d + %d = %d", x, y, sum);
}
可變參數(shù)和自動(dòng)裝箱還對(duì)java.lang.reflect API有一個(gè)實(shí)質(zhì)性的影響。那就是當(dāng)查找和調(diào)用方法時(shí)不再需要類和對(duì)象數(shù)組:
Method m = c.getMethod("put", Object.class,Object.class);
m.invoke(map, "key", "value");
如果我必須選擇一個(gè)最喜歡的可變參數(shù)方法,那么,將是java.util.Arrays.asList()。這個(gè)方法真是個(gè)用于創(chuàng)建不變的對(duì)象列表的方便的工廠方法。它接受任何數(shù)量的類型T的參數(shù)并且將它們作為L(zhǎng)ist<T>返回:
List<Integer> smallPrimes =
Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19);
能力
我們?cè)谏厦嬲務(wù)摿薘unnable和Callable,并且你毫無(wú)疑問(wèn)已經(jīng)聽說(shuō)過(guò)重要的Comparable, Serializable,和Cloneable接口。Java5.0新增加了五個(gè)重要的能力接口。第一個(gè),當(dāng)然,是java.lang.Iterable。你或許知道Java5.0新的for/in循環(huán)可以迭代數(shù)組和集合。你可能不知道它能夠?qū)θ魏螌?shí)現(xiàn)了可迭代(Iterable)接口的對(duì)象工作。因此,如果你想讓一個(gè)不是集合的數(shù)據(jù)結(jié)構(gòu)可以簡(jiǎn)單地迭代,只需實(shí)現(xiàn)Iterable接口。你要做的就是增加一個(gè)返回java.util.Iterator 的iterator()方法。當(dāng)然,寫這個(gè)迭代器(Iterator)可能不是那么簡(jiǎn)單的。
下面的代碼是一個(gè)實(shí)現(xiàn)了Iterable<String>(是的,Iterable是泛型的)的文本文件類,因而允許文本文件可以用for/in循環(huán)逐行的迭代。你可以用類似下面的代碼使用它:
TextFile textfile = new TextFile(new File(f), "UTF-8");
int lineNumber = 0;
for(String line : textfile)
System.out.printf("%6d: %s%n", ++lineNumber, line);
下面是TextFile的代碼。注意,迭代器不嘗試檢測(cè)對(duì)底層文件的并發(fā)的修改。如果你想自己做,看一看
java.nio.channels.FileLock。
import java.io.*;
import java.util.Iterator;
public class TextFile implements Iterable<String> {
File f;
String charsetName;
public TextFile(File f, String charsetName)
throws IOException
{
this.f = f;
this.charsetName = charsetName;
if (!f.exists())
throw new FileNotFoundException(f.getPath());
if (!f.canRead())
throw new IOException("Can't read: " +
f.getPath());
}
public Iterator<String> iterator() {
try {
return new TextFileIterator(f, charsetName);
}
catch(IOException e) {
throw new IllegalArgumentException(e);
}
}
static class TextFileIterator
implements Iterator<String>
{
BufferedReader in;
String nextline;
boolean closed = false;
public TextFileIterator(File f, String charsetName)
throws IOException
{
InputStream fis = new FileInputStream(f);
Reader isr =
new InputStreamReader(fis, charsetName);
in = new BufferedReader(isr);
getNextLine();
}
public boolean hasNext() {
return nextline != null;
}
public String next() {
String returnValue = nextline;
getNextLine();
return returnValue;
}
public void remove() {
throw new UnsupportedOperationException();
}
void getNextLine() {
if (!closed) {
try { nextline = in.readLine(); }
catch(IOException e) {
throw new IllegalArgumentException(e);
}
if (nextline == null) {
try { in.close(); }
catch(IOException ignored) {}
closed = true;
}
}
}
}
}
Iterable是到目前為止最重要的新能力接口,但是其它的也是非常的漂亮。接下來(lái),我們碰到j(luò)ava.lang.Appendable。一個(gè)Appendable對(duì)象可以追加字符或字符序列(或者一個(gè)字符序列的子序列)。實(shí)現(xiàn)者包括StringBuffer和StringBuilder(如果你還沒(méi)有聽說(shuō)過(guò)它,一定要看一看),Writer(及其子類),PrintStream,還有java.nio.CharBuffer。將可追加性從這些類中分離出來(lái)成為Appendable接口,使得新的java.util.Formatter類更強(qiáng)大:它能將文本格式化為任何可追加的對(duì)象,包括你自己的實(shí)現(xiàn)。(練習(xí)留給讀者:你能否將上面的TextFile類變得既可迭代又可追加么?)。
java.lang.Readable接口和Appendable相反:一個(gè)可讀對(duì)象可以將字符傳輸給給定的CharBuffer。java.io.Reader和它的全部子類都是可讀的(當(dāng)然了),CharBuffer本身也一樣。就像Appendable是為了java.util.Formatter的利益而創(chuàng)造,Readable是為了java.util.Scanner的利益而創(chuàng)造。(Java5.0增加了Scanner,連同F(xiàn)ormatter。這是Java對(duì)C的scanf()函數(shù)的適應(yīng),但是它(Scanner)不像Formatter之對(duì)應(yīng)于printf()的關(guān)系那樣密切。)
我想討論的最后兩個(gè)能力接口是java.io.Closeable和java.io.Flushable。如它們的名字暗示的,它們趨向于被任何類實(shí)現(xiàn),通過(guò)一個(gè)close()或者flush()方法。Closeable被所有的輸入和輸出流類,RandomAccessFile和Formatter實(shí)現(xiàn)。Flushable被輸出流類和Formatter實(shí)現(xiàn)。這些接口也是為了Formatter類的利益而定義。注意,Appendable對(duì)象(像StringBuilder)不總是可關(guān)閉或者可沖刷(flushable)。通過(guò)將可關(guān)閉性和可沖刷性分解出來(lái)成為這些接口,F(xiàn)ormatter的close()和flush()方法能夠決定它們操作的Appendable對(duì)象是否需要被關(guān)閉或被沖刷。(Java5.0還增加了第六個(gè)能力接口,并且它也是有關(guān)Formatter類的。那些想要控制它們的實(shí)例怎樣被格式化的類可以實(shí)現(xiàn)java.util.Formattable接口。然而這個(gè)接口的API是難用的,我不想談?wù)撍#?br>
@Override
毫無(wú)疑問(wèn),你已經(jīng)聽說(shuō)過(guò)能用元數(shù)據(jù)標(biāo)注Java5.0的類型和方法。但是你可能不熟悉增加到j(luò)ava.lang的標(biāo)準(zhǔn)標(biāo)注類型。我喜歡的第四個(gè)特性就是java.lang.Override標(biāo)注。當(dāng)你寫一個(gè)方法準(zhǔn)備覆蓋另一個(gè)的方法時(shí),用@Override來(lái)標(biāo)注它,這樣編譯器會(huì)進(jìn)行檢查來(lái)確保你確實(shí),實(shí)際上,覆蓋了你想覆蓋的方法。
如果你拼寫錯(cuò)了方法名字或者弄錯(cuò)了方法參數(shù),那么你實(shí)際上并沒(méi)有覆蓋那個(gè)你認(rèn)為你覆蓋了的方法。這樣就造成了一個(gè)如果不用@Override很難捕捉的臭蟲。我所以知道是因?yàn)槲业年P(guān)于Java1.4的新API特性的文章就講到了這個(gè)臭蟲,并且這個(gè)錯(cuò)誤至少有一年一直沒(méi)被檢測(cè)到(至少?zèng)]有被報(bào)告)。在那篇文章中,你可以在第一頁(yè)結(jié)尾看到我犯的錯(cuò)誤。那篇文章現(xiàn)在包含一個(gè)鏈接到我的博客入口,在那里我改正了這個(gè)臭蟲并且在代碼中增加了@Override聲明。
MatchResult
我喜歡的Java5.0的最后一個(gè)特性是java.util.regex.MatchResult。對(duì)于用于正則表達(dá)式的模式/匹配API我從來(lái)沒(méi)有真正非常滿意。Java5.0增加的MatchResult在讓我大大地更加滿意。當(dāng)使用一個(gè)不太平凡的模式(Pattern),每次調(diào)用匹配者(Matcher)的find()方法會(huì)生成許多狀態(tài):開始位置,結(jié)束位置,匹配的文本,同時(shí)還有模式的開始,結(jié)束,每個(gè)子表達(dá)式的文本。在Java5.0以前,你只能從Matcher獲取它們,通過(guò)在調(diào)用find()后再調(diào)用start(),end(),還有g(shù)roup(),如果需要的話。
然而,到了Java5.0,你可以只調(diào)用toMatchResult()來(lái)獲取MatchResult對(duì)象再獲取全部的狀態(tài),MatchResult對(duì)象可以保存并且可以以后再檢查。MatchResult像Matcher一樣有start(),end(),以及group()方法,并且,實(shí)際上,Matcher現(xiàn)在實(shí)現(xiàn)了MatchResult。
這里是一個(gè)有用的返回MatchResult的方法:
public static List<MatchResult> findAll(Pattern pattern,
CharSequence text) {
List<MatchResult> results =
new ArrayList<MatchResult>();
Matcher m = pattern.matcher(text);
while(m.find()) results.add(m.toMatchResult());
return results;
}
還有使用這個(gè)方法的代碼:
List<MatchResult> results = findAll(pattern, text);
for(MatchResult r : results) {
System.out.printf("Found '%s' at (%d,%d)%n",
r.group(), r.start(), r.end());
}
十六進(jìn)制浮點(diǎn)數(shù)字面值
我承諾談?wù)揓ava5.0的最晦澀的新語(yǔ)言特性。這就是:十六進(jìn)制格式的浮點(diǎn)常量!這里是奇異的詳情:一個(gè)十六進(jìn)制符號(hào)的浮點(diǎn)常量以0X或者0x開頭。隨后的十六進(jìn)制數(shù)字形成了數(shù)的基數(shù)。關(guān)鍵是這些數(shù)字可以包含一個(gè)小數(shù)點(diǎn)(一個(gè)十六進(jìn)制小數(shù)點(diǎn)?)。在基數(shù)后面是指數(shù),是必需的。十六進(jìn)制浮點(diǎn)常量使用p或者P而不是e或者E來(lái)引入指數(shù)。(想一下“冪”來(lái)幫助記憶)。P或者P后面是指數(shù),必須是一個(gè)十進(jìn)制數(shù),而不是十六進(jìn)制數(shù)。而且這是個(gè)以二為根的指數(shù),而不是以十為根。那就是,表示基數(shù)要乘以的2的冪。最后,整個(gè)常量可以跟隨一個(gè)f或者F來(lái)表示一個(gè)浮點(diǎn)常量,或者一個(gè)d或者D表示一個(gè)雙精度常量,就像一個(gè)十進(jìn)制浮點(diǎn)數(shù)一樣。
下面是一些例子:
double x = 0XaP0; // 10 * 2^0 = 10.0
double y = 0XfP2D; // 15 * 2^2 = 60.0
float z = 0Xf.aP1F; // (15 + 10/16ths) * 2^1 = 31.25f
// 用十進(jìn)制來(lái)打印
System.out.printf("%f %f %f%n", x, y, z);
// 用十六進(jìn)制來(lái)打印
System.out.printf("%a %a %a%n", x, y, z);
為什么Sun要對(duì)語(yǔ)言做這些?5.0的發(fā)行說(shuō)明說(shuō):
為了允許特定浮點(diǎn)值實(shí)現(xiàn)精確及可預(yù)見的規(guī)范,十六進(jìn)制符號(hào)可用于Float和Double的浮點(diǎn)字面值和字符串到浮點(diǎn)數(shù)的轉(zhuǎn)換方法中。
這點(diǎn)是合理的。十進(jìn)制小數(shù)像0.1是不能精確地用浮點(diǎn)格式表示的,并且如果你真的需要確切知道在一個(gè)浮點(diǎn)或者雙精度值中比特位是怎么設(shè)的,那么你真的想要一個(gè)十六進(jìn)制字面值。例如,F(xiàn)loat.MAX_VALUE的Javadoc指出最大的浮點(diǎn)值是0x1.fffffeP+127f。
如果你知道并且喜歡IEEE-754浮點(diǎn)標(biāo)準(zhǔn),那么十六進(jìn)制浮點(diǎn)字段值或許是你喜歡的一個(gè)特性。我只是認(rèn)為他們有趣。
一 從xml中裝載屬性
rmic —— rmi 編譯器
您不再需要使用 rmic —— rmi 編譯器工具——來(lái)生成最遠(yuǎn)程的接口存根。動(dòng)態(tài)代理的引入意味著通常由存根提供的信息可以在運(yùn)行時(shí)被發(fā)現(xiàn)。更多信息請(qǐng)參見 RMI 版本說(shuō)明。
新的 JVM profiling API (JSR-163)
該版本還包含一個(gè)更強(qiáng)大的本機(jī) profiling API,叫做 JVMTI。該 API 已經(jīng)在 JSR 163 中指定了,并由對(duì)改善的 profiling 接口的需求所推動(dòng)。但是,JVMTI 除了具有 profiling 功能之外,還想要涵蓋全范圍的本機(jī)內(nèi)部過(guò)程工具訪問(wèn),包括監(jiān)控工具、調(diào)試工具以及潛在的各種各樣的其他代碼分析工具。
//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");
}
}
改進(jìn)的診斷能力
如果沒(méi)有控制臺(tái)窗口可用,生成的 Stack 跟蹤就很笨拙。兩個(gè)新的 API —— getStackTrace 和 Thread.getAllStackTraces —— 以程序的方式提供該信息。
Hotspot JVM 包含一個(gè)致命的錯(cuò)誤處理程序(error hander),如果 JVM 異常中斷,它可以運(yùn)行用戶提供的腳本。使用 Hotspot JVM 可服務(wù)性代理連接器,調(diào)試工具也可以連接到一個(gè)掛起的 JVM 或者核心文件。
桌面客戶端
Java 桌面客戶端保留有 Java 平臺(tái)的一個(gè)關(guān)鍵組件,并且這一點(diǎn)成了 J2SE 1.5 中許多改進(jìn)的焦點(diǎn)。
Windows XP
Click to Enlarge
Linux/Redhat
Click to Enlarge
更多信息請(qǐng)參見 Character 中的 Unicode 部分。
格式:
<properties>
<comment>Hi</comment>
<entry key="id">1</entry>
<entry key="name">rocie</entry>
<entry key="email">rocie@sina.com</entry>
</properties>
|
通過(guò)以下方法加載:
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("d:/jdk5/properties/test.xml");
prop.loadFromXML(fis);
prop.list(System.out);
System.out.println("Name: " + prop.getProperty("name"));
|
將xml文件放在WEB-INF/classes/目錄下,可以防止對(duì)路徑的硬編碼
InputStream is = PropertiesTest.class.getClassLoader().getResourceAsStream("rocie.xml");
Properties ps = new Properties();
ps.loadFromXML(is);
System.out.println("name:"+ps.getProperty("name"));
|
通過(guò)以下方法保存:
Properties prop = new Properties();
prop.setProperty("id", "2");
prop.setProperty("name", "彭大雙");
prop.setProperty("email", "pds@dotraining.com");
FileOutputStream fos = new FileOutputStream("d:/jdk5/properties/pds.xml");
prop.storeToXML(fos, "彭大雙","gbk");
fos.close();
|
xml文件細(xì)節(jié):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Hi</comment>
<entry key="id">1</entry>
<entry key="name">rocie</entry>
<entry key="email">rocie@sina.com</entry>
</properties>
|
DTD文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- DTD for properties -->
<!ELEMENT properties ( comment?, entry* ) >
<!ATTLIST properties version CDATA #FIXED "1.0">
<!ELEMENT comment (#PCDATA) >
<!ELEMENT entry (#PCDATA) >
<!ATTLIST entry key CDATA #REQUIRED>
|
注:?表示0或1;*表示0至無(wú)限;+表示至少一個(gè)
二 并發(fā)集合
問(wèn)題:ConcurrentModificationException、fail-fast
當(dāng)遍歷一個(gè)Iterator時(shí),如果該Iterator對(duì)應(yīng)的List里的元素發(fā)生改變,則拋出這個(gè)異常。
解決方法:java.util.concurrent
用CopyOnWriteArrayList代替原來(lái)的ArrayList
copy-on-write:這意味著如果有大量的讀(即 get() ) 和迭代,不必同步操作以照顧偶爾的寫(即 add() )調(diào)用。對(duì)于新的 CopyOnWriteArrayList 和 CopyOnWriteArraySet 類,所有可變的(mutable)操作都首先取得后臺(tái)數(shù)組的副本,對(duì)副本進(jìn)行更改,然后替換副本。這種做法保證了在遍歷自身更改的集合時(shí),永遠(yuǎn)不會(huì)拋出 ConcurrentModificationException 。遍歷集合會(huì)用原來(lái)的集合完成,而在以后的操作中使用更新后的集合。
三用 for/in 在 Java 5.0 中增強(qiáng)循環(huán)
public static List<Integer> list = new ArrayList<Integer>();
public static int[] is = new int[]{1,2,3,4,65,456};
static
{
for(int i=0;i<100;i++)
list.add(i);
}
public static void main(String args[])
{
for(Integer i:list)
System.out.println(i);
System.out.println("-------other for each--------");
for(int i:is)
System.out.println(i);
}
|
四枚舉類型 enum
public class EnumTest {
private Color color;
public static enum Color {red,yellow,blue,green};
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public static void main(String args[])
{
for(Color c:Color.values())
{
System.out.println("name:"+c.name()+"ordinal:"+c.ordinal());
}
EnumTest et = new EnumTest();
et.setColor(Color.red);
Color c = et.getColor();
switch(c)
{
case red: System.out.println("red:"+c.name()+c.ordinal());
break;
case yellow: System.out.println("yellow"+c.name()+c.ordinal());
break;
default : System.out.println("over");
}
}
}
|
并發(fā)實(shí)用程序
并發(fā)實(shí)用程序庫(kù)由 Doug Lea 定義在 JSR-166 中,是 J2SE 1.5 平臺(tái)中流行的并發(fā)軟件包的一個(gè)特殊版本。它提供強(qiáng)大的、高級(jí)別的線程構(gòu)造,包括 executors(這是一個(gè)線程任務(wù)框架)、線程安全隊(duì)列、Timers、鎖(包括原子鎖)和其他同步原語(yǔ)。
并發(fā)實(shí)用程序庫(kù)由 Doug Lea 定義在 JSR-166 中,是 J2SE 1.5 平臺(tái)中流行的并發(fā)軟件包的一個(gè)特殊版本。它提供強(qiáng)大的、高級(jí)別的線程構(gòu)造,包括 executors(這是一個(gè)線程任務(wù)框架)、線程安全隊(duì)列、Timers、鎖(包括原子鎖)和其他同步原語(yǔ)。
著名的旗語(yǔ)(semaphore)是這樣一個(gè)鎖。旗語(yǔ)與現(xiàn)在使用的 wait 的使用方式相同,用于限制對(duì)一塊代碼的訪問(wèn)。旗語(yǔ)更加靈活,并且也允許許多并發(fā)的線程訪問(wèn),同時(shí)允許您在獲得一個(gè)鎖之前對(duì)它進(jìn)行測(cè)試。下面的例子使用剛好一個(gè)旗語(yǔ),也叫做二進(jìn)制旗語(yǔ)。更多信息請(qǐng)參見 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
balance=balance+10; //protected value
s.release(); //return semaphore token
rmic —— rmi 編譯器
您不再需要使用 rmic —— rmi 編譯器工具——來(lái)生成最遠(yuǎn)程的接口存根。動(dòng)態(tài)代理的引入意味著通常由存根提供的信息可以在運(yùn)行時(shí)被發(fā)現(xiàn)。更多信息請(qǐng)參見 RMI 版本說(shuō)明。
可擴(kuò)展性和性能
1.5 版本承諾在可擴(kuò)展性和性能方面的改進(jìn),新的重點(diǎn)在于啟動(dòng)時(shí)間和內(nèi)存占用,使它更加易于以最大的速度部署應(yīng)用程序。
1.5 版本承諾在可擴(kuò)展性和性能方面的改進(jìn),新的重點(diǎn)在于啟動(dòng)時(shí)間和內(nèi)存占用,使它更加易于以最大的速度部署應(yīng)用程序。
最重大的一個(gè)更新是引入了 Hotspot JVM 中的類數(shù)據(jù)共享。該技術(shù)不僅在多個(gè)正在運(yùn)行的 JVM 之間共享只讀數(shù)據(jù),而且改進(jìn)了啟動(dòng)時(shí)間,因?yàn)楹诵牡?JVM 類都是預(yù)先打包的。
性能工效是 J2SE 1.5 中的一個(gè)新特性,這意味著如果您一直使用的是以前版本中專門的 JVM 運(yùn)行時(shí)選項(xiàng), 那么可能值得不用選項(xiàng)或者用很少的選項(xiàng)重新驗(yàn)證您的性能。
監(jiān)控和可管理性
監(jiān)控和可管理性是 Java 平臺(tái)中的 RAS (Reliability, Availability, Serviceability,即可*性、可用性、可服務(wù)性) 的一個(gè)關(guān)鍵組件。
監(jiān)控和可管理性是 Java 平臺(tái)中的 RAS (Reliability, Availability, Serviceability,即可*性、可用性、可服務(wù)性) 的一個(gè)關(guān)鍵組件。
JVM Monitoring & Management API (JSR-174) 指定一組全面的可以從正在運(yùn)行的 JVM 進(jìn)行監(jiān)控的 JVM internals。 該信息可通過(guò) JMX (JSR-003) MBeans 訪問(wèn)到,也可以使用 JMX 遠(yuǎn)程接口 (JSR-160) 和行業(yè)標(biāo)準(zhǔn) SNMP 工具而遠(yuǎn)程訪問(wèn)得到。
最有用的一個(gè)特性是一個(gè)低內(nèi)存檢測(cè)程序。當(dāng)超過(guò)閥值時(shí),JMX MBeans 可以通知已注冊(cè)的偵聽程序。更多信息請(qǐng)參見 javax.management 和 java.lang.management。
為了了解新的 API 是多么容易使用,下面報(bào)告了 Hotspot JVM 中內(nèi)存堆的詳細(xì)使用情況。
import java.lang.management.*;
import java.util.*;
import javax.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());
}
}
}
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 profiling API (JSR-163)
該版本還包含一個(gè)更強(qiáng)大的本機(jī) profiling API,叫做 JVMTI。該 API 已經(jīng)在 JSR 163 中指定了,并由對(duì)改善的 profiling 接口的需求所推動(dòng)。但是,JVMTI 除了具有 profiling 功能之外,還想要涵蓋全范圍的本機(jī)內(nèi)部過(guò)程工具訪問(wèn),包括監(jiān)控工具、調(diào)試工具以及潛在的各種各樣的其他代碼分析工具。
該實(shí)現(xiàn)包含一個(gè)用于字節(jié)碼裝置(instrumentation)——Java 編程語(yǔ)言裝置服務(wù)(Java Programming Language Instrumentation Services,JPLIS)的機(jī)制。這使得分析工具只在需要的地方添加額外的配置信息(profiling)。該技術(shù)的優(yōu)點(diǎn)是,它允許更加集中的分析,并且限制了正在運(yùn)行的 JVM 上的 profiling 工具的引用。該裝置甚至可以在運(yùn)行時(shí)和類加載時(shí)動(dòng)態(tài)地生成,并且可以作為類文件預(yù)先處理。
下面這個(gè)例子創(chuàng)建了一個(gè)裝置鉤(instrumentation hook),它可以從磁盤加載類文件的一個(gè)已修改的版本。要運(yùn)行該測(cè)試,可利用 java -javaagent:myBCI BCITest 啟動(dòng) JRE。
//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");
}
}
改進(jìn)的診斷能力
如果沒(méi)有控制臺(tái)窗口可用,生成的 Stack 跟蹤就很笨拙。兩個(gè)新的 API —— getStackTrace 和 Thread.getAllStackTraces —— 以程序的方式提供該信息。
StackTraceElement e[]=Thread.currentThread().getStackTrace();
for (int i=0; i <e.length; i++) {
System.out.println(e);
}
System.out.println("\n"+Thread.getAllStackTraces());
for (int i=0; i <e.length; i++) {
System.out.println(e);
}
System.out.println("\n"+Thread.getAllStackTraces());
Hotspot JVM 包含一個(gè)致命的錯(cuò)誤處理程序(error hander),如果 JVM 異常中斷,它可以運(yùn)行用戶提供的腳本。使用 Hotspot JVM 可服務(wù)性代理連接器,調(diào)試工具也可以連接到一個(gè)掛起的 JVM 或者核心文件。
-XX:OnError="command"
-XX:OnError="pmap %p"
-XX:OnError="gdb %p"
-XX:OnError="gdb %p"
optional %p used as process id
桌面客戶端
Java 桌面客戶端保留有 Java 平臺(tái)的一個(gè)關(guān)鍵組件,并且這一點(diǎn)成了 J2SE 1.5 中許多改進(jìn)的焦點(diǎn)。
這個(gè) Beta 版本包含啟動(dòng)時(shí)間和內(nèi)存占用方面的一些早期改進(jìn)。該版本不僅更快,并且 Swing 工具集采用了一個(gè)暫新的叫做 Ocean 的主題。
通過(guò)建立 J2SE 1.4.2 中的更新,GTK 和 Windows XP 外觀方面有了更進(jìn)一步的改進(jìn)。
Windows XP
Click to Enlarge
Linux/Redhat
Click to Enlarge
具有最新 OpenGL 驅(qū)動(dòng)程序并且選擇了圖形卡的 Linux 和 Solaris 用戶,可以使用下面的運(yùn)行時(shí)屬性從 Java2D 獲得本機(jī)硬件加速:
java -Dsun.java2d.opengl=true -jar Java2D.
Linux 版本也具有快速的 X11 Toolkit,叫做 XAWT,默認(rèn)情況下是啟用的。如果您需要與 motif 版本進(jìn)行比較,可以使用下面的系統(tǒng)屬性:
java -Dawt.toolkit=sun.awt.motif.MToolkit -jar Notepad.jar
(X11 Toolkit 叫做 sun.awt.X11.XToolkit)
X11 Toolkit 也使用 XDnD 協(xié)議,所以您可以在 Java 和其他應(yīng)用(比如 StarOffice 或 Mozilla)之間拖放簡(jiǎn)單的組件。
其他特性
核心 XML 支持
J2SE 1.5 引入了核心 XML 平臺(tái)的幾個(gè)修訂,包括 XML 1.1 和 Namespace、XML Schema、SAX 2.0.1、XSLT 和快速 XLSTC 編譯器,以及最后的 DOM 第 3 層支持。
核心 XML 支持
J2SE 1.5 引入了核心 XML 平臺(tái)的幾個(gè)修訂,包括 XML 1.1 和 Namespace、XML Schema、SAX 2.0.1、XSLT 和快速 XLSTC 編譯器,以及最后的 DOM 第 3 層支持。
除了支持核心 XML 之外,未來(lái)版本的 Java Web Services Developer Pack 將交付最新的 Web 服務(wù)標(biāo)準(zhǔn):JAX-RPC & SAAJ (WSDL/SOAP)、JAXB、XML Encryption and Digital Signature,以及用于注冊(cè)的 JAXR。
輔助字符支持
32 位的輔助字符支持作為傳輸?shù)?Unicode 4.0 支持的一部分,已經(jīng)慎重地添加到該平臺(tái)。輔助字符被編碼為一對(duì)特殊的 UTF16 值,以生成一個(gè)不同的字符或者碼點(diǎn)(codepoint)。一個(gè)代理對(duì)(surrogate pair)是一個(gè)高 UTF16 值和后面的一個(gè)低 UTF16 值的組合。這些高值和低值來(lái)自一個(gè)特殊范圍的 UTF16 值。
32 位的輔助字符支持作為傳輸?shù)?Unicode 4.0 支持的一部分,已經(jīng)慎重地添加到該平臺(tái)。輔助字符被編碼為一對(duì)特殊的 UTF16 值,以生成一個(gè)不同的字符或者碼點(diǎn)(codepoint)。一個(gè)代理對(duì)(surrogate pair)是一個(gè)高 UTF16 值和后面的一個(gè)低 UTF16 值的組合。這些高值和低值來(lái)自一個(gè)特殊范圍的 UTF16 值。
一般來(lái)說(shuō),當(dāng)使用 String 或者字符序列時(shí),核心 API 庫(kù)將透明地為您處理新的輔助字符。但是因?yàn)?Java "char" 仍然保留為 16 位,所以非常少的一些使用 char 作為參數(shù)的方法,現(xiàn)在有了足夠的可以接受 int 值的方法,其中 int 值可以代表新的更大的值。特別是 Character 類,具有附加的方法來(lái)檢索當(dāng)前的字符和接下來(lái)的字符,以便檢索輔助的碼點(diǎn)值,如下所示:
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));
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));
更多信息請(qǐng)參見 Character 中的 Unicode 部分。
JDBC RowSets
JDBC 行集支持有兩個(gè)主要的更新。CachedRowSet 包含從數(shù)據(jù)庫(kù)檢索的行的內(nèi)存中的集合。但是它們也是不連接的,這意味著以后更新可以與數(shù)據(jù)庫(kù)重新同步。
JDBC 行集支持有兩個(gè)主要的更新。CachedRowSet 包含從數(shù)據(jù)庫(kù)檢索的行的內(nèi)存中的集合。但是它們也是不連接的,這意味著以后更新可以與數(shù)據(jù)庫(kù)重新同步。
另一個(gè)組件是 WebRowSet,它使用數(shù)據(jù)庫(kù)行通過(guò) XML 來(lái)傳輸數(shù)據(jù)。
參考資料:
New Language Features for Ease of Development in the Java 2 Platform, Standard Edition 1.5: http://java.sun.com/features/2003/05/bloch_qa.html
New Language Features for Ease of Development in the Java 2 Platform, Standard Edition 1.5: http://java.sun.com/features/2003/05/bloch_qa.html
Tiger Component JSRs
003 Java Management Extensions (JMX) Specification http://jcp.org/en/jsr/detail?id=3
003 Java Management Extensions (JMX) Specification http://jcp.org/en/jsr/detail?id=3
013 Decimal Arithmetic Enhancement http://jcp.org/en/jsr/detail?id=13
014 Add Generic Types To The Java Programming Language http://jcp.org/en/jsr/detail?id=14
028 Java SASL Specification http://jcp.org/en/jsr/detail?id=28
114 JDBC Rowset Implementations http://jcp.org/en/jsr/detail?id=114
133 Java Memory Model and Thread Specification Revision http://jcp.org/en/jsr/detail?id=133
160 Java Management Extensions (JMX) Remote API 1.0 http://jcp.org/en/jsr/detail?id=160
163 Java Platform Profiling Architecture http://jcp.org/en/jsr/detail?id=163
166 Concurrency Utilities http://jcp.org/en/jsr/detail?id=166
174 Monitoring and Management Specification for the Java Virtual Machine http://jcp.org/en/jsr/detail?id=174
175 A Metadata Facility for the Java Programming Language http://jcp.org/en/jsr/detail?id=175
200 Network Transfer Format for Java Archives http://jcp.org/en/jsr/detail?id=200
201 Extending the Java Programming Language with Enumerations, Autoboxing, Enhanced for Loops and Static Import http://jcp.org/en/jsr/detail?id=201
204 Unicode Supplementary Character Support http://jcp.org/en/jsr/detail?id=204
206 Java API for XML Processing (JAXP) 1.3 http://jcp.org/en/jsr/detail?id=206
posted on 2007-06-22 10:49 BigMouse 閱讀(1373) 評(píng)論(0) 編輯 收藏 所屬分類: JAVA學(xué)習(xí)