1. 当我们希望对泛型的类型参数的类型进行限制的时候(好拗口), 我们就应该使用有界类型参数(Bounded Type Parameters). 有界类型参数使用extends关键字后面接上边界类型来表示, 注意: 这里虽然用的是extends关键字, 却不仅限于继承了父类E的子类, 也可以代指显现了接口E的类. 仍以Box类为例:
public class Box<T> { private T obj; public Box() {} public T getObj() {
return obj;
} public void setObj(T obj) {
this.obj = obj;
} public Box(T obj) {
super();
this.obj = obj;
} public <Q extends Number> void inspect(Q q) {
System.out.println(obj.getClass().getName());
System.out.println(q.getClass().getName());
}
}
我加入了public <Q extends Number> void inspect(Q q){...}方法, 该方法的泛型只能是Number的子类.
Box<String> b = new Box<>();
b.setObj("Hello");
b.inspect(12);
b.inspect(1.5);
// b.inspect(true); // 编译出错
2. 界类型参数除了规定泛型的范围之外, 还允许我们调用边界类型所拥有的方法(因为所有类型参数都是边界类型或边界类型的子类), 如:
public class NatureNumber<T extends Integer> { private T t; public Box() {} public NatureNumber(T t) {
this.t = t;
} public boolean isEven() {
return t.intValue() % 2 == 0;
} // ...
}
3. 多边界:
上面的例子展示的是单边界的泛型, 我们还可以使用多边界泛型:
<T extends A & B & C>
但是多边界使用时其实只能继承一个父类, 并且要将他写在第一个位置上. 其他的都是其实现的接口, 如:
class A { /* ... */ }
interface B { /* ... */ }
interface C { /* ... */ }
class D <T extends A & B & C> { /* ... */ }
如果A不在第一个位置上就会编译出错.