The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
There may be times when you want to restrict the types that can be used as type arguments in a parameterized type. 有时,您可能希望限制可在参数化类型中用作类型参数的类型。For example, a method that operates on numbers might only want to accept instances of 例如,对数字进行操作的方法可能只希望接受Number
or its subclasses. Number
或其子类的实例。This is what bounded type parameters are for.这就是受限类型参数的用途。
To declare a bounded type parameter, list the type parameter's name, followed by the 要声明有界类型参数,请列出类型参数的名称,后跟extends
keyword, followed by its upper bound, which in this example is Number
. extends
关键字,再后跟其上限,在本例中为Number
。Note that, in this context, 注意,在此上下文中,extends
is used in a general sense to mean either "extends" (as in classes) or "implements" (as in interfaces).extends
在一般意义上表示“extends”(在类中)或“implements”(在接口中)。
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! } }
By modifying our generic method to include this bounded type parameter, compilation will now fail, since our invocation of 通过修改泛型方法以包含此有界类型参数,编译现在将失败,因为我们调用inspect
still includes a 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
In addition to limiting the types you can use to instantiate a generic type, bounded type parameters allow you to invoke methods defined in the bounds:除了限制可用于实例化泛型类型的类型外,有界类型参数还允许调用在边界中定义的方法:
public class NaturalNumber<T extends Integer> { private T n; public NaturalNumber(T n) { this.n = n; } public boolean isEven() { return n.intValue() % 2 == 0; } // ... }
The isEven method invokes the intValue method defined in the Integer class through n.isEven方法通过n调用Integer类中定义的intValue方法。
The preceding example illustrates the use of a type parameter with a single bound, but a type parameter can have multiple bounds:前面的示例演示了使用具有单个边界的类型参数,但类型参数可以具有多个边界:
<T extends B1 & B2 & B3>
A type variable with multiple bounds is a subtype of all the types listed in the bound. 具有多个边界的类型变量是边界中列出的所有类型的子类型。If one of the bounds is a class, it must be specified first. 如果其中一个边界是类,则必须首先指定它。For example:例如:
Class A { /* ... */ } interface B { /* ... */ } interface C { /* ... */ } class D <T extends A & B & C> { /* ... */ }
If bound A is not specified first, you get a compile-time error:如果未首先指定绑定A,则会出现编译时错误:
class D <T extends B & A & C> { /* ... */ } // compile-time error