對java 5除generic外的new features的總結
The for-each loop
for (type_name variable_name : [instance of Iterable<T>] or [array]) {}
跟 .net 的 foreach 不同的是, Iterable 中的 type parameter 或 array 中的 element type 必須是 for 中使用的 type 或者其子類。
以下情況不適合使用 foreach :
1.?????? 當需要刪除或者替換 current element 時。
2.?????? 當需要同時訪問一個以上的 Iterable<T> 或者 array 時。
Autoboxing
一般的代碼經常會使用 boxing 跟 unboxing ,如:
List list = new ArrayList();
int i = 0;
list.add(new Integer(i)); // boxing
i = ((Integer) list.get(0)).intValue(); // unboxing
采用了 autoboxing 之后, java 能夠自動在 primitive type 它相應的 wrapper 之間進行轉換。
// autoboxing
list.add(i);
i = list.get(0);
以 Integer 為例,以下幾點是需要注意的:
1.?????? 當試圖將值為 null 的 Integer 轉為 int 時,會有 NullPointerException 。
int i = (Integer) null;
2.?????? 對于 == 操作符,當它作用在 int 上時是做值的比較,作用于 Integer 上時是做 reference 的比較。
int i1 = 0;
Integer i2 = new Integer(0);
i1 == i2; // return true
i2 == i1; // return true
(Integer) i1 == i2; // return false
3.?????? 如果頻繁使用 autoboxing 將不利于代碼的運行效率。
Enums
public enum Test { // 1
A, B(1), C { public boolean test1() { return true; } } /* 5 */ ; // 2
private int i = 0;
Test() {} // 3
private Test(int i) { this.i = i; } // 3
public boolean test1() { return false; } // 5
public boolean test2(Test test) { return test != A && test !=B; } // 6
// 7
public boolean test3() {
????? switch (this) {
case A: return false;
case B: return false;
default: return true;
}
}
}
Enum 跟一般的類有很多相似之處,它們都能夠實現多個接口,能夠定義方法、類變量,除了這些相似點之外, enum 有如下的特性:
1.?????? 必須使用 enum 關鍵字來定義,不能用 extends 指定父類,假如 enum 的名字為 Test ,則它自動繼承 Enum<Test> 。與此同時, enum 還自動實現 Serializable 跟 comparable 接口,并且自動重載了部分 Object 的方法。
2.?????? 所有的可用 enum constant 必須放在第一行,用逗號格開,以分號結束(如果后面沒有其他的代碼,則分號可以省略)。通過專門設計,使得 Serial form 可以支持后續新增的 enum constant 。
3.?????? 可以定義若干不同的構造函數,構造函數只能用 private 修飾符(可以省略掉 private ),當構造函數需要輸入參數時, enum constant 的定義中必須提供這些參數的值。
4.?????? 自動增加了 values() 和 valueOf ( Class<T>, String )、 valueOf(String) 三個靜態方法。
5.?????? 可以為 enum constant 定義 constant-specific 方法。
6.?????? 在代碼中可以引用前面所定義的類型。
7.?????? 由于 switch 可以應用于 int 跟 enum 類型,在代碼中可以使用 ”switch (this) {…}” 語句。
8.?????? 在 java.util 中有專為 enum 設計的高效率的 EnumSet 跟 EnumMap ,其中 EnumSet 提供對方法以使 enum 支持位與( bit flags )操作。
Varargs
在方法的參數列表上,如果類型后面加上三個點,則表示該參數可能作為數組或者多個參數傳入,如:
public void test(int… arguments) {}
…
test(1);
test(1, 2, 3);
test(new int[0]);
跟 .net 類似的, varargs 必須作為方法的最后一個參數。如果對使用 varargs 的方法進行重載,則在調用該方法時,有可能 compiler 無法識別代碼究竟調用的是哪個方法,此時會有編譯錯誤。
Static Import
Static import 用來 import 類中的靜態變量或靜態方法,使用了 static import 之后,這些使用這些靜態變量和靜態方法時將不需要使用類名。
import static java.lang.Math.PI;
import static java.lang.Math.*;
Annotations
Annotation 的定義
public @interface Test {
????? int value();
????? String name() default “test”;
}
定義 annotation 使用 @interface 關鍵字。 annotation 能使用的類型為 primitive 、 String 、 Class 、 enums 以及以以上類型為 element type 的數組。使用 default 關鍵字能夠設定默認值,默認值必須是 compile time constants 。
Annotation 的使用的語法跟 java doc 的語法相似,為了區分這兩者, annotation 的命名不能使用已有的 java doc 中所用的名字。
在 java.lang.annotation 中存在若干 mata-annotation ,用于 annotate 其他的 annotation 。
Annotation 的使用
首先,必須 import annotation 所在的包, annotation 可以放在在任何 static 、 public 、 final 關鍵字可以使用的地方,建議把 annotation 放在最前面。
@Test(value=0)
public class A {
@Test(Value=0, name=”abc”) public void test(@Test(0) Object o) {}
}
對 annotation 中各個變量的賦值作為 name value pair 被放在括號內,同時用逗號格開,如果 annotation 中沒有任何變量或者所有變量都有默認值,則可以省去賦值部分(連同括號),如果 annotation 中有一個名字為 value 的變量,同時沒有其他的變量或者其他的變量都有默認值,則可以只提供值而省略 element name 和等號。
讀出 annotation 的包含的信息
通過 reflection 可以讀出 annotation 所包含的信息,有一部分 annotation 通過使用 meta-annotation 被聲明為 runtime 不可知,這時通過分析 byte code 才能得到其信息。
posted on 2006-12-27 09:36 junky 閱讀(304) 評論(0) 編輯 收藏 所屬分類: java