本文中,我們將討論幾個在
JDK1.5
中新的語言特征,包括:
泛型(
Generics
)
--
為集合(
collections
)提供編譯時類型安全,無需每刻從
Collections
取得一個對象就進(jìn)行強(qiáng)制轉(zhuǎn)換(
cast
)
增強(qiáng)的
“for”
循環(huán)(
Enhanced For loop
)
--
減少迭代器
(iterator)
的潛在錯誤(
error-proneness
)
自動置入
/
自動取出(
Autoboxing/unboxing
)
--
無需在基本類型(
primitive types
)(例如
double
)和包裝類型(
wrapper types
)(例如
Double
)之間人工地進(jìn)行轉(zhuǎn)換。
類型安全的枚舉(
Typesafeenums
)
--
提供類型安全枚舉模式的各項好處。
靜態(tài)導(dǎo)入(
Static import
)
--
無需在使用其他類的靜態(tài)成員變量前綴其類名
.
這將使得代碼更為簡潔。
元數(shù)據(jù)(
Metadata
)
--
使編程人員避免編寫樣板化代碼(
boiler plate code
),并提供機(jī)會進(jìn)行宣告式程式設(shè)計
(declarative programming)
。
讓我們詳細(xì)討論每個新特性,并看一些例子。
泛型(
Generics
)
泛型是
JDK1.5
中一個最
“
酷
”
的特征。通過引入泛型,我們將獲得編譯時類型的安全和運行時更小地拋出
ClassCastExceptions
的可能。在
JDK1.5
中,你可以聲明一個集合將接收
/
返回的對象的類型。在
JDK1.4
中,創(chuàng)建雇員名字的清單(
List
)需要一個集合對象,像下面的語句:
List listOfEmployeeName = new ArrayList();
在
JDK1.5
中,你將使用下面語句
List<String> listOfEmployeeName = new ArrayList<String>();
最
“
酷
”
的是,如果你試圖插入非
string
類型的值,你將在編譯時發(fā)現(xiàn)并且修正這類問題。沒有泛型,你會發(fā)現(xiàn)這樣一個
bug
,當(dāng)你的客戶調(diào)用后會告訴你,你所編寫的程序拋出
ClassCastException
異常而崩潰。
另外,當(dāng)你從集合中得到一個元素時你無需進(jìn)行強(qiáng)制轉(zhuǎn)換。故原先為:
String employeeName = ((String) listOfEmployee.get(i));
而下面的語句將比上面的更加簡單:
String employeeName = listOfEmployee.get(i);
不清楚對象的類型而強(qiáng)制轉(zhuǎn)換對象是不合理的,并且更重要的是,它將在運行時失敗。假使用戶無意間傳入一個包含
string buffers
類型而非
string
類型的集合,那結(jié)果會怎樣呢。在
Listing A
中,客戶被要求傳入一個編譯器無法強(qiáng)制的
strings
類型集合。
Listing B
中顯示了同樣的方法使用泛型是如何實現(xiàn)的。
Listing A
staticbooleancheckName(Collection employeeNameList, String name) {
for (Iteratori = employeeNamList.iterator(); i.hasNext(); ) {
String s = (String) i.next();
if(s.equals(name)){
return true;
//print employee name here ......
}
}
return false;
}
Listing B
staticbooleancheckName(Collection<String> employeeNameList, String name) {
for (Iteratori = employeeNamList.iterator(); i.hasNext(); ) {
if(i.next().equals(name)){
return true;
//print employee name here ......
}
}
return false;
}
現(xiàn)在,通過方法簽名可以清楚知道輸入集合必須只能包含
strings
。如果客戶試圖傳入一個包含
string buffers
的集合,程序?qū)⒉粫幾g。同時注意,該方法不包含任何強(qiáng)制轉(zhuǎn)換。它只需要短短一行,一旦你習(xí)慣泛型后,它也更加清晰。
在
JDK
當(dāng)前版本下的
For
循環(huán)語法如下:
void printAll(Collection c) {
for (Iteratori = c.iterator(); i.hasNext(); ) {
Employee emp = (Employee)i.next();
System.out.println(emp.getName());
}
}
現(xiàn)在,用增強(qiáng)的
For
語句實現(xiàn)相同方法:
voidprintAll(Collection c) {
for (Object o : c)
System.out.println((TimerTask)o).getName());
}
在這類
For
循環(huán)中,你應(yīng)該將
":"
看成
"in"
,所以,在該例中可以看成
"for Object o in c"
。你可以發(fā)現(xiàn)這種
For
循環(huán)更具可讀性。
自動置入
/
自動取出(
Autoboxing/unboxing
)
Java
有基本數(shù)據(jù)類型,在這些基本數(shù)據(jù)類型周圍又有包裝類。通常,編程人員需要將一種類型轉(zhuǎn)換成另一種。看看
Listing C.
中的代碼片斷。
Listing C
public class Employee {
private static final Integer CHILD = new Integer(0);
public static void main(String args[]) {
//code for adding n to an Integer
int n=10;
Integer age= new Integer(30);
Integer ageAfterTenYear= new Integer(age.intValue +10);
}
}
請注意,用于計算
ageAfterTenYear
的內(nèi)循環(huán)代碼看上去是多么雜亂。現(xiàn)在,在
Listing D.
中看看相同的程序使用
autoboxing
重寫后的樣子。
Listing D
public class Employee {
public static void main(String args[]) {
int n=10;
Integer age= new Integer(30);
Integer ageAfterTenYear= age +10;
}
}
有一件事值得注意的:在先前,如果你取出(
unbox
)
Null
值,它將變?yōu)?/span>
0
。在次代碼中,編譯器將自動地轉(zhuǎn)換
Integer
為
int
然后加上
10
,接著將其轉(zhuǎn)換回
Integer.
。
類型安全的枚舉(
Typesafeenums
)
類型安全枚舉提供下列特性:
他們提供編譯時類型安全。
他們都是對象,因此你不需要將他們放入集合中。
他們作為一種類的實現(xiàn),因此你可以添加一些方法。
他們?yōu)槊杜e類型提供了合適的命名空間。
他們打印的值具有情報性(
informative
)
—
如果你打印一個整數(shù)枚舉(
intenum
),你只是看見一個數(shù)字,它可能并不具有情報性。
例一:
enum Season { winter, spring, summer, fall }
例二:
public enum Coin {
penny(1), nickel(5), dime(10), quarter(25);
Coin(int value) { this.value = value; }
private final int value;
public int value() { return value; }
}
靜態(tài)導(dǎo)入(
Static import
)
靜態(tài)導(dǎo)入使代碼更易讀。通常,你要使用定義在另一個類中的常量(
constants
),像這樣:
import org.yyy.pkg.Increment;
class Employee {
public Double calculateSalary(Double salary{
return salary + Increment.INCREMENT * salary;
}
}
當(dāng)時使用靜態(tài)導(dǎo)入,我們無需為常量名前綴類名就能使用這些常量,像這樣:
import static org.yyy.pkg.Increment;
class Employee {
public Double calculateSalary(Double salary{
return salary + INCREMENT * salary;
}
}
注意,我們可以調(diào)用
INCREMENT
這一常量而不要使用類名
Increment.
。
元數(shù)據(jù)(
Metadata
)
元數(shù)據(jù)特征志于使開發(fā)者們借助廠商提供的工具可以進(jìn)行更簡易的開發(fā)。看一看
Listing E.
中的代碼。
Listing E
import org.yyy.hr;
public interface EmployeeI extends Java.rmi.Remote {
public String getName()
throwsJava.rmi.RemoteException;
public String getLocation ()
throwsJava.rmi.RemoteException;
}
public class EmployeeImpl implements EmployeeI {
public String getName(){
}
public String getLocation (){
}
}
通過元數(shù)據(jù)的支持,你可以改寫
Listing E
中的代碼為:
import org.yyy.hr;
public class Employee {
@Remote public String getName() {
...
}
@Remote public public String getLocation() {
...
}
}
正像你所看到的,所有樣板化的代碼都不見了。
這些新特性和規(guī)格說明將在
JDK1.5
中實現(xiàn)。它將提供
Java
編程社區(qū)更多的選擇以編寫魯棒的、可擴(kuò)展的代碼。認(rèn)真的
Java
編程人員將感到著手去熟悉這一
Java
編程語言的新版本是很有益的。
凡是有該標(biāo)志的文章,都是該blog博主Caoer(草兒)原創(chuàng),凡是索引、收藏
、轉(zhuǎn)載請注明來處和原文作者。非常感謝。