printf, Formatter)
List<Integer> list = new ArrayList<Integer>();
list.add(new Integer(1));
// list.add("str"); // 編譯錯誤!
Integer i = list.get(0); // 無需強制轉型
核心價值:編譯期阻擋 ClassCastException,API 文檔化,消除散佈的轉型碼。
public class Box<E> {
private E element;
public void set(E e) { element = e; }
public E get() { return element; }
}
慣例:單一大寫字母 E (Element), T (Type), K (Key), V (Value)。
Integer是Number子類,但List<Integer>不是List<Number>子類。
若允許,可將 Double 放入 List<Integer> 破壞類型安全。解決方案見下「通配符」。
| 語法 | 含義 | 適用場景 |
|---|---|---|
<? extends T> | T 及其子類 (上界) | 唯讀取資料 (Producer) |
<? super T> | T 及其父類 (下界) | 唯寫入資料 (Consumer) |
<?> | 無限制通配符 | 僅操作 Object 方法 |
// PECS 原則:Producer Extends, Consumer Super
void printAll(List<? extends Number> list) { // 讀
for (Number n : list) System.out.println(n);
}
void addIntegers(List<? super Integer> list) { // 寫
list.add(1);
}
Java 泛型為編譯期特性,執行期資訊被擦除。List<Integer> 執行期只是 List。影響:
new T(), instanceof List<String>, new T[10]
for (String s : list) { ... } // 適用 Iterable 與陣列
Integer i = 10; // 自動裝箱: Integer.valueOf(10)
int n = i; // 自動拆箱: i.intValue()
// 注意:null 自動拆箱拋 NPE;頻繁裝箱產生物件影響效能
enum Season { SPRING, SUMMER, AUTUMN, WINTER }
// 可攜帶欄位、方法、實作介面,每個常數為單例
void printAll(String... args) { for (String s : args) ... }
printAll("a", "b", "c"); // 內部為 String[]
import static java.lang.Math.*;
import static java.util.Collections.*;
double r = sqrt(PI); // 直接用方法/常數名
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test { String value() default ""; }
// 執行期透過反射讀取,驅動測試框架、ORM 映射等
System.out.printf("Hello %s, age %d%n", name, age);
String msg = String.format("%,.2f", 12345.678); // "12,345.68"
J2SE 5.0 是 Java 語言演進的里程碑。泛型 雖有擦除限制,但極大提升了類型安全與 API 表達力;註解 開啟了宣告式程式設計新紀元;其餘特性皆旨在減少樣板碼、提升可讀性。建議配合 IDE (Eclipse 3.1+, NetBeans 4.0) 體驗完整支援。