受限的类型参数

Author Avatar
贾康 11月 11, 2016

#受限的类型参数
有时我们可能想要限制类型参数的可选类型。比如说一个操作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

下一页