Java 使用泛型的约束类型
有时你可能想限制在参数化类型中可以作为类型参数使用的类型。例如,一个对数字进行操作的方法可能只想接受数字的实例或其子类。这就是有界类型参数的作用。
- 有时我们不希望整个类都被参数化。在这种情况下,我们可以创建一个Java泛型方法。因为构造函数是一种特殊的方法,所以我们也可以在构造函数中使用泛型类型。
- 假设我们想限制可以在参数化类型中使用的对象的类型。例如,在一个比较两个对象的方法中,我们想确保接受的对象是可比较的。
- 这些方法的调用与无界方法类似,只是如果我们将尝试使用任何非可比较的类,它将抛出编译时错误。
如何在Java中声明一个有界类型参数 ?
- 列出类型参数的名称。
- 和extends关键字一起
- 和它的上界。(在下面的例子中,c是 A。 )
语法
<T extends **superClassName** >
注意,在这个上下文中,extends在一般意义上是指 “扩展”(如在类中)。另外,This规定T只能被superClassName或superClassName的子类取代。因此,超类定义了一个包容的、上限的。
让我们举个例子,看看如何用泛型实现有界类型(扩展超类)
// This class only accepts type parameters as any class
// which extends class A or class A itself.
// Passing any other type will cause compiler time error
class Bound<T extends A>
{
private T objRef;
public Bound(T obj){
this.objRef = obj;
}
public void doRunTest(){
this.objRef.displayClass();
}
}
class A
{
public void displayClass()
{
System.out.println("Inside super class A");
}
}
class B extends A
{
public void displayClass()
{
System.out.println("Inside sub class B");
}
}
class C extends A
{
public void displayClass()
{
System.out.println("Inside sub class C");
}
}
public class BoundedClass
{
public static void main(String a[])
{
// Creating object of sub class C and
// passing it to Bound as a type parameter.
Bound<C> bec = new Bound<C>(new C());
bec.doRunTest();
// Creating object of sub class B and
// passing it to Bound as a type parameter.
Bound<B> beb = new Bound<B>(new B());
beb.doRunTest();
// similarly passing super class A
Bound<A> bea = new Bound<A>(new A());
bea.doRunTest();
}
}
输出
Inside sub class C
Inside sub class B
Inside super class A
现在,我们只限于类型A和它的子类,所以它对任何其他类型的子类都会抛出一个错误。
// This class only accepts type parameters as any class
// which extends class A or class A itself.
// Passing any other type will cause compiler time error
class Bound<T extends A>
{
private T objRef;
public Bound(T obj){
this.objRef = obj;
}
public void doRunTest(){
this.objRef.displayClass();
}
}
class A
{
public void displayClass()
{
System.out.println("Inside super class A");
}
}
class B extends A
{
public void displayClass()
{
System.out.println("Inside sub class B");
}
}
class C extends A
{
public void displayClass()
{
System.out.println("Inside sub class C");
}
}
public class BoundedClass
{
public static void main(String a[])
{
// Creating object of sub class C and
// passing it to Bound as a type parameter.
Bound<C> bec = new Bound<C>(new C());
bec.doRunTest();
// Creating object of sub class B and
// passing it to Bound as a type parameter.
Bound<B> beb = new Bound<B>(new B());
beb.doRunTest();
// similarly passing super class A
Bound<A> bea = new Bound<A>(new A());
bea.doRunTest();
Bound<String> bes = new Bound<String>(new String());
bea.doRunTest();
}
}
输出:
error: type argument String is not within bounds of type-variable T
多重边界
有边界的类型参数可以用于方法,也可以用于类和接口。
Java Generics也支持多重边界,即在这种情况下,A可以是一个接口或类。如果A是类,那么B和C应该是接口。我们不能在多个边界中拥有一个以上的类。
语法
<T extends **superClassName** & **Interface** >
class Bound<T extends A & B>
{
private T objRef;
public Bound(T obj){
this.objRef = obj;
}
public void doRunTest(){
this.objRef.displayClass();
}
}
interface B
{
public void displayClass();
}
class A implements B
{
public void displayClass()
{
System.out.println("Inside super class A");
}
}
public class BoundedClass
{
public static void main(String a[])
{
//Creating object of sub class A and
//passing it to Bound as a type parameter.
Bound<A> bea = new Bound<A>(new A());
bea.doRunTest();
}
}
输出
Inside super class A