1. 泛型中指定父类的基本概念
  • 在 Java 泛型中,我们可以使用extends关键字来指定类型参数的上限,即这个类型参数必须是指定父类或者其子类。这样做的好处是可以在编译时期就对类型进行一定的限制,使得代码更加安全和易于理解。例如,我们有一个Animal类,DogCatAnimal的子类,我们可以定义一个泛型类或者泛型方法,让它的类型参数只能是Animal或者Animal的子类。
  1. 在泛型类中指定父类
  • 语法示例


class GenericClass<T extends Animal> {
    private T element;
    public GenericClass(T element) {
        this.element = element;
    }
    public T getElement() {
        return element;
    }
}
  • 解释说明
  • 在上述代码中,GenericClass是一个泛型类,它有一个类型参数T,并且通过T extends Animal指定了T的类型上限为Animal类。这意味着在使用GenericClass时,传递给T的类型必须是Animal或者Animal的子类。例如,我们可以这样使用这个泛型类:


Dog dog = new Dog();
GenericClass<Dog> dogGenericClass = new GenericClass<>(dog);
Animal animal = dogGenericClass.getElement();

  • 这里DogAnimal的子类,所以可以作为T的类型来实例化GenericClass。而在GenericClass内部,element的类型被确定为T,由于TAnimal或者其子类,所以可以安全地将element赋值给Animal类型的变量animal
  1. 在泛型方法中指定父类
  • 语法示例

class GenericMethodExample {
    public static <T extends Animal> T method(T element) {
        System.out.println("The element is a kind of Animal.");
        return element;
    }
}
  • 解释说明
  • 这是一个包含泛型方法的类。method方法是一个泛型方法,它有一个类型参数T,并且通过T extends Animal指定了T的类型上限。在方法内部,可以像处理Animal类型一样处理参数element,因为编译器已经知道element的类型是Animal或者Animal的子类。例如,可以这样调用这个泛型方法:


Cat cat = new Cat();
Cat resultCat = GenericMethodExample.method(cat);

  • 当调用method方法时,传递的参数catCat类的实例,CatAnimal的子类,符合method方法对类型参数T的要求,所以方法可以正确执行,并且返回值可以安全地赋值给Cat类型的变量resultCat
  1. 多个类型参数和上限指定(高级用法)
  • 语法示例


class ComplexGenericClass<T extends Animal, U extends Serializable> {
    private T element1;
    private U element2;
    public ComplexGenericClass(T element1, U element2) {
        this.element1 = element1;
        this.element2 = element2;
    }
    // 省略getter和setter方法
}
  • 解释说明
  • 这里定义了一个更复杂的泛型类ComplexGenericClass,它有两个类型参数TUT的类型上限是AnimalU的类型上限是Serializable。这意味着在使用这个泛型类时,第一个参数的类型必须是Animal或者其子类,第二个参数的类型必须是Serializable或者其子类。这种用法可以在处理多个相关但又有不同类型要求的参数时,提供更精确的类型控制。例如,可以这样使用这个泛型类:


Dog dog = new Dog();
String serializedData = "Serialized data";
ComplexGenericClass<Dog, String> complexObject = new ComplexGenericClass<>(dog, serializedData);

  • 在这个例子中,DogAnimal的子类,String实现了Serializable接口,所以符合ComplexGenericClass对类型参数的要求。