1. 當我們希望對泛型的類型參數的類型進行限制的時候(好拗口), 我們就應該使用有界類型參數(Bounded Type Parameters). 有界類型參數使用extends關鍵字后面接上邊界類型來表示, 注意: 這里雖然用的是extends關鍵字, 卻不僅限於繼承了父類E的子類, 也可以代指顯現了接口E的類. 仍以Box類為例:
1 public class Box<T> { 2 3 private T obj; 4 5 public Box() {} 6 7 public T getObj() { 8 return obj; 9 } 10 11 public void setObj(T obj) { 12 this.obj = obj; 13 } 14 15 public Box(T obj) { 16 super(); 17 this.obj = obj; 18 } 19 20 public <Q extends Number> void inspect(Q q) { 21 System.out.println(obj.getClass().getName()); 22 System.out.println(q.getClass().getName()); 23 } 24 }
我加入了public <Q extends Number> void inspect(Q q){...}方法, 該方法的泛型只能是Number的子類.
1 Box<String> b = new Box<>(); 2 b.setObj("Hello"); 3 b.inspect(12); 4 b.inspect(1.5); 5 // b.inspect(true); // 編譯出錯
2. 界類型參數除了規定泛型的范圍之外, 還允許我們調用邊界類型所擁有的方法(因為所有類型參數都是邊界類型或邊界類型的子類), 如:
1 public class NatureNumber<T extends Integer> { 2 3 private T t; 4 5 public Box() {} 6 7 public NatureNumber(T t) { 8 this.t = t; 9 } 10 11 public boolean isEven() { 12 return t.intValue() % 2 == 0; 13 } 14 15 // ... 16 }
3. 多邊界:
上面的例子展示的是單邊界的泛型, 我們還可以使用多邊界泛型:
<T extends A & B & C>
但是多邊界使用時其實只能繼承一個父類, 並且要將他寫在第一個位置上. 其他的都是其實現的接口, 如:
1 class A { /* ... */ } 2 interface B { /* ... */ } 3 interface C { /* ... */ } 4 class D <T extends A & B & C> { /* ... */ }
如果A不在第一個位置上就會編譯出錯.