J2SE 5.0的三個新特性
這裏介紹J2SE 5.0中三個比較重要的特性: 枚舉類型, 註釋類型, 範型.
J2SE 5.0 (Tiger)的發佈是Java語言發展史上的一個重要的里程碑, 是迄今爲止在 Java 編程方面所取得的最大進步.
J2SE 5.0提供了很多令人激動的特性.這些特性包括範型(generics)的支持, 枚舉類型(enumeration)的支持, 元數據(metadata)的支持, 自動拆箱(unboxing)/裝箱(autoboxing), 可變個數參數(varargs), 靜態導入(static imports), 以及新的線程架構(Thread framework).
一. 枚舉類型
J2SE 5.0 以及之前的JDK有兩種基本方法可以來定義新類型:通過Classes 以及Interface. 對於大部分面向對象編程來說,
這兩種方法看起來似乎足夠了.但是在一些特殊情況下,這些方法就不適合.例如,我們想定義一個類型 Priority, 它只能接
受 High, Medium, Low 三種值. 其他任何值都是非法的.J2SE 5.0 以前的JDK是可以構造這種類型的,但是需要做很多工作,
有可能會帶來如不安全(類型安全性問題???)等潛在問題,而J2SE 5.0的枚舉類型(Enum) 能避免這些問題.
public enum Priority {High, Medium, Low };
它包括一個關鍵字enum ,一個新枚舉類型的名字 Priority 以及爲Priority定義的一組值.
二. 註釋類型
J2SE 5.0提供了很多新的特性。其中的一個很重要的特性,就是對元數據(Metadata)的支持。在J2SE5.0中,這種元數據叫作
註釋(Annotation)。通過使用註釋, 程序開發人員可以在不改變原有邏輯的情況下,在源文件嵌入一些補充的信息。代碼分析
工具,開發工具和部署工具可以通過這些補充信息進行驗證或者進行部署。舉個例子,比如說你希望某個方法的參數或者返回
值不爲空,雖然我們可以在Java doc中說明,但是表達同樣意思的說法有很多,比如"The return value should not be
null"或者"null is not allowed here"。測試工具很難根據這些語言來分析出程序員所期望的前提條件(Pre-condition)和執
行後的條件(Post-condition)。 而使用註釋(Annotation),這個問題就可以輕而易舉的解決了。
J2SE5.0支持用戶自己定義註釋。定義註釋很簡單,註釋是由@Interface關鍵字來聲明的。比如下面是一個最簡單的注
釋(Annotation)。
public @interface TODO{}
標記註釋的用法
@MarkerAnnotation
@SingleValueAnnotation("some value")
@MultipleValueAnnotation(
key1=value1,
key2=value2,
key3=value3,
)
在程序中不僅可以使用自己定義的註釋,還可以使用J2SE5.0中內建的註釋類型。J2SE 5.0中預定義了三種註釋註釋類型:
Override :java.lang.Override 表示當前的方法重寫了父類的某個方法,如果父類的對應的方法並不存在,將會發生編譯錯
誤。
Deprecated:java.lang.Deprecated 表示 並不鼓勵使用當前的方法或者域變量。
SuppressWarnings: java.lang.SuppressWarnings關閉編譯器告警,這樣,在編譯1.5之前的代碼的時候,不會出現大量不關
心的無關的告警。
值得注意的是,J2SE5.0還提供了四種用於註釋的註釋類型。有以下的四種:
1. Target:用來指定這個註釋(Annotation)是爲哪種類型而定義的。比如,這個類型可能只是爲method定義的。比
如override,不能用@override來修飾class或者field。
2.Retention:Retention的策略可以從以下三種中選取:
RetentionPolicy.SOURCE:編譯器編譯之後會會從class file中除去註釋(Annotation)。
Retention.CLASS:註釋(Annotation)保留在class file中,但是VM不會處理。
RetentionPolicy.RUNTIME,:註釋(Annotation)保留在class file,VM會進行處理。
請注意,如果你希望在運行時查找到這些註釋在什麼地方被用到,一定要在定義註釋的時候,選擇RetentionPolicy.RUNTIME,
否則即使你用註釋修飾了類變量或者方法,在運行時也沒有辦法獲得這個信息的。
3.Documented:這個註釋(Annotation)將作爲public API的一部分。
4.Inherited : 假設註釋(Annotation)定義的時候使用了Inherited,那麼如果這個註釋(Annotation)修飾某個class,這
個類的子類也被這個註釋(Annotation)所修飾。
小結
所謂元數據,指的是關於信息的信息。一般而言,代碼分析工具,測試工具或者部署工具會使用元數據來產生配置信息以及使
用配置信息產生控制邏輯。這些工具通常使用Java的反射特性,重構元數據的信息,並對這些信息進行解釋。
新的技術會不斷改變程序設計和開發人員的設計思想。那麼註釋(Annotation)給我們帶來了什麼呢? 僅僅在代碼分析,或者
是開發測試框架和部署框架的時候纔有用麼? 在我們的應用中充分的利用元數據,可以提高的軟件的質量和可維護性。
三. 範型
J2SE 5.0中的最顯著的變化之一是添加對泛型類型的支持. 在J2SE 1.4 以及之前的版本中, Java程序並不是類型安全的. 例
如, Collection framework中定義的List, Map等容器類的元素都是Object類型, 即這個類包含的元素是Object對象. 使用這
種方式實現的列表, 可以用來操作整數, 實數, 字符串或者任何對象類型. 例如
List stringList = new ArrayList();
stringList.add("abcde");
String str = (String)stringList.get(0);
這種方法實現的列表需要使用強制類型轉換(又稱顯示造型), 因此不是類型安全的. 在上面這段代碼種, 雖然變量名
爲stringList, 但是我們仍然可以把一個整型對象添加到這個隊列中, 例如,
stringList.add(new Integer(5));
在這種情況下, 從字符列表中獲取對象時, 強制類型轉換就會導致運行時異常.
範型是Java邁向類型安全的一個重要步驟, 使用範型可以構造出類型安全的代碼.
所謂範型是指類型參數化(parameterized types). Java是一種強類型的語言, 在J2SE 1.4以及以前的版本中, 我們在定義一
個Java類, 接口或者方法的時候, 必須指定變量的類型. 在聲明範型類、接口或者函數時, 定義變量的時候不指定某些變量的
具體類型, 而是用一個類型參數代替. 在使用這個類, 接口, 或者方法的時候, 這個類型參數由一個具體類型所代替.
下面的例子中介紹瞭如何創建一個最簡單範型類
public class GenSample<T> {}
類名後面帶有<T>表明了這個類是範型類, 其中T被成爲類型參數(type parameter), 在使用範型的時候, 類型參數可以被替換
爲任何的類類型, 但是不能是原始類型(primitive type), 例如int, double.
下面通過一個列表的例子來具體說明如果聲明範型類和類型參數的用法.
public class GenList <T>{
private T[] elements;
private int size = 0;
private int length = 0;
public GenList(int size) {
elements = (T[])new Object[size];
this.size = size;
}
public T get(int i) {
if (i < length) {
return elements[i];
}
return null;
}
public void add(T e) {
if (length < size - 1)
elements[length++] = e;
}
}
在列表的例子中, 類型參數T被用來表示列表中的元素的類型, 即, 這個列表中的元素是T類型的.
在使用這個列表時, 這個類型參數T會被具體的類型所替代.
注意, 由於T時類型參數不是具體的類, 所以不能使用new操作符創建T的對象,例如new T(), 或者, new T[10].
在J2SE 5.0中, 不僅僅可以聲明範型類, 也可以聲明範型接口, 聲明範型接口和聲明範型類的語法類似, 也是在接口命稱後面
加上<T>. 例如,
public interface GenInterface<T> {
void func(T t);
}
在聲明範型類的時候, 可是使用多個類型參數. 多個類型參數之間用逗號分開, 例如,
public class GenMap<T, V> {}
範型是J2SE 5.0所提供的一項強大的功能, 使用範型可以創建類型安全的、可重用的代碼, 雖然目前Java的範型還無法和C++的範型相提並論, 但是, 隨着Java語言本事的演進, 範型會在Java語言中發揮更大的作用的.
J2SE 5.0 (Tiger)的發佈是Java語言發展史上的一個重要的里程碑, 是迄今爲止在 Java 編程方面所取得的最大進步.
J2SE 5.0提供了很多令人激動的特性.這些特性包括範型(generics)的支持, 枚舉類型(enumeration)的支持, 元數據(metadata)的支持, 自動拆箱(unboxing)/裝箱(autoboxing), 可變個數參數(varargs), 靜態導入(static imports), 以及新的線程架構(Thread framework).
一. 枚舉類型
J2SE 5.0 以及之前的JDK有兩種基本方法可以來定義新類型:通過Classes 以及Interface. 對於大部分面向對象編程來說,
這兩種方法看起來似乎足夠了.但是在一些特殊情況下,這些方法就不適合.例如,我們想定義一個類型 Priority, 它只能接
受 High, Medium, Low 三種值. 其他任何值都是非法的.J2SE 5.0 以前的JDK是可以構造這種類型的,但是需要做很多工作,
有可能會帶來如不安全(類型安全性問題???)等潛在問題,而J2SE 5.0的枚舉類型(Enum) 能避免這些問題.
public enum Priority {High, Medium, Low };
它包括一個關鍵字enum ,一個新枚舉類型的名字 Priority 以及爲Priority定義的一組值.
二. 註釋類型
J2SE 5.0提供了很多新的特性。其中的一個很重要的特性,就是對元數據(Metadata)的支持。在J2SE5.0中,這種元數據叫作
註釋(Annotation)。通過使用註釋, 程序開發人員可以在不改變原有邏輯的情況下,在源文件嵌入一些補充的信息。代碼分析
工具,開發工具和部署工具可以通過這些補充信息進行驗證或者進行部署。舉個例子,比如說你希望某個方法的參數或者返回
值不爲空,雖然我們可以在Java doc中說明,但是表達同樣意思的說法有很多,比如"The return value should not be
null"或者"null is not allowed here"。測試工具很難根據這些語言來分析出程序員所期望的前提條件(Pre-condition)和執
行後的條件(Post-condition)。 而使用註釋(Annotation),這個問題就可以輕而易舉的解決了。
J2SE5.0支持用戶自己定義註釋。定義註釋很簡單,註釋是由@Interface關鍵字來聲明的。比如下面是一個最簡單的注
釋(Annotation)。
public @interface TODO{}
標記註釋的用法
@MarkerAnnotation
@SingleValueAnnotation("some value")
@MultipleValueAnnotation(
key1=value1,
key2=value2,
key3=value3,
)
在程序中不僅可以使用自己定義的註釋,還可以使用J2SE5.0中內建的註釋類型。J2SE 5.0中預定義了三種註釋註釋類型:
Override :java.lang.Override 表示當前的方法重寫了父類的某個方法,如果父類的對應的方法並不存在,將會發生編譯錯
誤。
Deprecated:java.lang.Deprecated 表示 並不鼓勵使用當前的方法或者域變量。
SuppressWarnings: java.lang.SuppressWarnings關閉編譯器告警,這樣,在編譯1.5之前的代碼的時候,不會出現大量不關
心的無關的告警。
值得注意的是,J2SE5.0還提供了四種用於註釋的註釋類型。有以下的四種:
1. Target:用來指定這個註釋(Annotation)是爲哪種類型而定義的。比如,這個類型可能只是爲method定義的。比
如override,不能用@override來修飾class或者field。
2.Retention:Retention的策略可以從以下三種中選取:
RetentionPolicy.SOURCE:編譯器編譯之後會會從class file中除去註釋(Annotation)。
Retention.CLASS:註釋(Annotation)保留在class file中,但是VM不會處理。
RetentionPolicy.RUNTIME,:註釋(Annotation)保留在class file,VM會進行處理。
請注意,如果你希望在運行時查找到這些註釋在什麼地方被用到,一定要在定義註釋的時候,選擇RetentionPolicy.RUNTIME,
否則即使你用註釋修飾了類變量或者方法,在運行時也沒有辦法獲得這個信息的。
3.Documented:這個註釋(Annotation)將作爲public API的一部分。
4.Inherited : 假設註釋(Annotation)定義的時候使用了Inherited,那麼如果這個註釋(Annotation)修飾某個class,這
個類的子類也被這個註釋(Annotation)所修飾。
小結
所謂元數據,指的是關於信息的信息。一般而言,代碼分析工具,測試工具或者部署工具會使用元數據來產生配置信息以及使
用配置信息產生控制邏輯。這些工具通常使用Java的反射特性,重構元數據的信息,並對這些信息進行解釋。
新的技術會不斷改變程序設計和開發人員的設計思想。那麼註釋(Annotation)給我們帶來了什麼呢? 僅僅在代碼分析,或者
是開發測試框架和部署框架的時候纔有用麼? 在我們的應用中充分的利用元數據,可以提高的軟件的質量和可維護性。
三. 範型
J2SE 5.0中的最顯著的變化之一是添加對泛型類型的支持. 在J2SE 1.4 以及之前的版本中, Java程序並不是類型安全的. 例
如, Collection framework中定義的List, Map等容器類的元素都是Object類型, 即這個類包含的元素是Object對象. 使用這
種方式實現的列表, 可以用來操作整數, 實數, 字符串或者任何對象類型. 例如
List stringList = new ArrayList();
stringList.add("abcde");
String str = (String)stringList.get(0);
這種方法實現的列表需要使用強制類型轉換(又稱顯示造型), 因此不是類型安全的. 在上面這段代碼種, 雖然變量名
爲stringList, 但是我們仍然可以把一個整型對象添加到這個隊列中, 例如,
stringList.add(new Integer(5));
在這種情況下, 從字符列表中獲取對象時, 強制類型轉換就會導致運行時異常.
範型是Java邁向類型安全的一個重要步驟, 使用範型可以構造出類型安全的代碼.
所謂範型是指類型參數化(parameterized types). Java是一種強類型的語言, 在J2SE 1.4以及以前的版本中, 我們在定義一
個Java類, 接口或者方法的時候, 必須指定變量的類型. 在聲明範型類、接口或者函數時, 定義變量的時候不指定某些變量的
具體類型, 而是用一個類型參數代替. 在使用這個類, 接口, 或者方法的時候, 這個類型參數由一個具體類型所代替.
下面的例子中介紹瞭如何創建一個最簡單範型類
public class GenSample<T> {}
類名後面帶有<T>表明了這個類是範型類, 其中T被成爲類型參數(type parameter), 在使用範型的時候, 類型參數可以被替換
爲任何的類類型, 但是不能是原始類型(primitive type), 例如int, double.
下面通過一個列表的例子來具體說明如果聲明範型類和類型參數的用法.
public class GenList <T>{
private T[] elements;
private int size = 0;
private int length = 0;
public GenList(int size) {
elements = (T[])new Object[size];
this.size = size;
}
public T get(int i) {
if (i < length) {
return elements[i];
}
return null;
}
public void add(T e) {
if (length < size - 1)
elements[length++] = e;
}
}
在列表的例子中, 類型參數T被用來表示列表中的元素的類型, 即, 這個列表中的元素是T類型的.
在使用這個列表時, 這個類型參數T會被具體的類型所替代.
注意, 由於T時類型參數不是具體的類, 所以不能使用new操作符創建T的對象,例如new T(), 或者, new T[10].
在J2SE 5.0中, 不僅僅可以聲明範型類, 也可以聲明範型接口, 聲明範型接口和聲明範型類的語法類似, 也是在接口命稱後面
加上<T>. 例如,
public interface GenInterface<T> {
void func(T t);
}
在聲明範型類的時候, 可是使用多個類型參數. 多個類型參數之間用逗號分開, 例如,
public class GenMap<T, V> {}
範型是J2SE 5.0所提供的一項強大的功能, 使用範型可以創建類型安全的、可重用的代碼, 雖然目前Java的範型還無法和C++的範型相提並論, 但是, 隨着Java語言本事的演進, 範型會在Java語言中發揮更大的作用的.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.