Java教程是针对JDK 8编写的。本页面描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
请参阅Java语言变更了解Java SE 9及其后续版本中更新的语言功能的摘要。
请参阅JDK发行说明以获取有关所有JDK版本的新功能、增强功能以及已删除或已弃用选项的信息。
有时候,您可能希望限制可以用作参数化类型的类型。例如,一个操作数字的方法可能只想接受Number
或其子类的实例。这就是有界类型参数的用途。
要声明有界类型参数,请列出类型参数的名称,后跟extends
关键字,再跟上其上界,例如此示例中的Number
。请注意,在此上下文中,extends
的意义是“扩展”(适用于类)或“实现”(适用于接口)。
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"); // 错误:这仍然是String! } }
通过修改我们的泛型方法以包含这个有界类型参数,编译将会失败,因为我们对inspect
的调用仍然包括一个String
:
Box.java:21: <U>inspect(U) in Box<java.lang.Integer> cannot be applied to (java.lang.String) integerBox.inspect("10"); ^ 1 error
除了限制可以用于实例化泛型类型的类型之外,有界类型参数还允许您调用在上界中定义的方法:
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方法通过n调用了Integer类中定义的intValue方法。
前面的示例说明了使用带有单个上界的类型参数,但是类型参数可以有多个上界:
<T extends B1 & B2 & B3>
具有多个上界的类型变量是所有上界中列出的类型的子类型。如果其中一个上界是类,则必须首先指定它。例如:
Class A { /* ... */ } interface B { /* ... */ } interface C { /* ... */ } class D <T extends A & B & C> { /* ... */ }
如果没有首先指定A作为上界,将会得到一个编译时错误:
class D <T extends B & A & C> { /* ... */ } // 编译时错误