Java 使用泛型的约束类型

Java 使用泛型的约束类型

有时你可能想限制在参数化类型中可以作为类型参数使用的类型。例如,一个对数字进行操作的方法可能只想接受数字的实例或其子类。这就是有界类型参数的作用。

  • 有时我们不希望整个类都被参数化。在这种情况下,我们可以创建一个Java泛型方法。因为构造函数是一种特殊的方法,所以我们也可以在构造函数中使用泛型类型。
  • 假设我们想限制可以在参数化类型中使用的对象的类型。例如,在一个比较两个对象的方法中,我们想确保接受的对象是可比较的。
  • 这些方法的调用与无界方法类似,只是如果我们将尝试使用任何非可比较的类,它将抛出编译时错误。

如何在Java中声明一个有界类型参数

  1. 列出类型参数的名称。
  2. 和extends关键字一起
  3. 和它的上界。(在下面的例子中,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

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程