#受限的类型参数
有时我们可能想要限制类型参数的可选类型。比如说一个操作Number类的方法可能只想接受Number类型以及他的子类,这就是我们为什么要使用受限类型参数。
为了声明一个受限类型参数,列出类型参数的名字,后边是extends关键字,再然后是他的上界,在这个例子中是Number。需要注意的是在这个情境中,Extends既表示继承(对类来说)也表示实现(对接口来说)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Box<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } public <U extends Number> void inspect(U u){ System.out.println("T: " + t.getClass().getName()); System.out.println("U: " + u.getClass().getName()); } public static void main(String[] args) { Box<Integer> integerBox = new Box<Integer>(); integerBox.set(new Integer(10)); integerBox.inspect("some text"); // error: this is still String! } }
|
如果我们的inspect方法使用了受限的类型参数,比较就会失败,因为我们调用inspect方法时使用了String。
1 2 3 4 5
| Box.java:21: <U>inspect(U) in Box<java.lang.Integer> cannot be applied to (java.lang.String) integerBox.inspect("10"); ^ 1 error
|
除了以上的功能,受限类型参数允许你调用提供限制类的方法。
1 2 3 4 5 6 7 8 9 10 11 12
| public class NaturalNumber<T extends Integer> { private T n; public NaturalNumber(T n) { this.n = n; } public boolean isEven() { return n.intValue() % 2 == 0; } // ... }
|
isEven方法调用了Integer类的intValue方法。
###多个受限参数
上面的例子阐述了类型参数的单个限制,但是一个类型参数可以有多个限制条件。
1
| <T extends B1 & B2 & B3>
|
一个有多个限定的类型参数的声明如上所示。这个参数必须继承或实现所有的限制类或接口。需要注意的是限制类必须第一个声明。举例来说:
1 2 3 4 5
| Class A { /* ... */ } interface B { /* ... */ } interface C { /* ... */ } class D <T extends A & B & C> { /* ... */ }
|
如果不这样做,我们就会得到编译错误。
1
| class D <T extends B & A & C> { /* ... */ } // compile-time error
|
下一页