Java中具有泛型的有界类型
有时您可能想要限制可用作参数化类型中的类型参数的类型。例如,对数字进行操作的方法可能只想接受 Numbers 或其子类的实例。这就是有界类型参数的用途。
- 有时我们不希望整个类都被参数化。在这种情况下,我们可以创建一个Java泛型方法。由于构造函数是一种特殊的方法,我们也可以在构造函数中使用泛型类型。
- 假设我们要限制参数化类型中可以使用的对象类型。例如,在比较两个对象的方法中,我们希望确保接受的对象是 Comparables。
- 这些方法的调用类似于无界方法,只是如果我们尝试使用任何非 Comparable 类,则会抛出编译时错误。
如何在Java中声明有界类型参数?
- 列出类型参数的名称,
- 与 extends 关键字一起
- 并按其上限。 (在下面的例子中 c 是A 。)
句法
请注意,在这种情况下,extends 在一般意义上用于表示“扩展”(如在类中)。此外,这指定 T 只能被 superClassName 或 superClassName 的子类替换。因此,超类定义了一个包容性的上限。
让我们举一个例子,说明如何用泛型实现有界类型(扩展超类)。
Java
// 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
{
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 bec = new Bound(new C());
bec.doRunTest();
// Creating object of sub class B and
// passing it to Bound as a type parameter.
Bound beb = new Bound(new B());
beb.doRunTest();
// similarly passing super class A
Bound bea = new Bound(new A());
bea.doRunTest();
}
}
Java
// 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
{
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 bec = new Bound(new C());
bec.doRunTest();
// Creating object of sub class B and
// passing it to Bound as a type parameter.
Bound beb = new Bound(new B());
beb.doRunTest();
// similarly passing super class A
Bound bea = new Bound(new A());
bea.doRunTest();
Bound bes = new Bound(new String());
bea.doRunTest();
}
}
Java
class Bound
{
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 bea = new Bound(new A());
bea.doRunTest();
}
}
输出
Inside sub class C
Inside sub class B
Inside super class A
现在,我们仅限于类型 A 及其子类,因此它会为任何其他类型的子类抛出错误。
Java
// 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
{
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 bec = new Bound(new C());
bec.doRunTest();
// Creating object of sub class B and
// passing it to Bound as a type parameter.
Bound beb = new Bound(new B());
beb.doRunTest();
// similarly passing super class A
Bound bea = new Bound(new A());
bea.doRunTest();
Bound bes = new Bound(new String());
bea.doRunTest();
}
}
输出 :
error: type argument String is not within bounds of type-variable T
多重界限
有界类型参数可以与方法以及类和接口一起使用。
Java泛型也支持多个边界,即,在这种情况下,A 可以是接口或类。如果 A 是类,那么 B 和 C 应该是接口。我们不能在多个范围内拥有多个类。
句法:
Java
class Bound
{
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 bea = new Bound(new A());
bea.doRunTest();
}
}
输出
Inside super class A