Java随笔-泛型

什么是泛型

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

假定我们有这样一个需求:写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?

答案是可以使用 Java 泛型。

使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。


泛型的写法

一般我们会有以下两种写法
>>
InterfaceName 是泛型要实现的接口,一般来说我们使用第一种方法声明泛型就可以满足需求.

class Animal implements Comparable{
    protected int age;

    public Animal(int age){
        this.age = age;
    }

    public void move() {
        System.out.println("动物可以移动");
    }

    @Override
    public int compareTo(@NonNull Animal animal) {
        return this.age-animal.age;
    }
}

class Main {
    public static > void mySort1(List list){
        Collections.sort(list);
    }
    public static > void mySort2(List list){
        Collections.sort(list);
    }
    public static void main(String[] args) {
        List animals = new ArrayList<>();
        animals.add(new Animal(2));
        animals.add(new Animal(1));

        mySort1(animals);
        mySort2(animals);
    }
}

比如上边这段代码,声明两个排序方法,分别使用上述两种方式声明泛型变量.
Animal实现了Comparable接口所以无论使用哪种声明泛型变量的排序方法都可以调用.看不出两种声明方式有什么区别.

下边看这段代码

class Animal implements Comparable{
    protected int age;

    public Animal(int age){
        this.age = age;
    }

    public void move() {
        System.out.println("动物可以移动");
    }

    @Override
    public int compareTo(@NonNull Animal animal) {
        return this.age-animal.age;
    }
}
//增加Dog 继承与 Animal
class Dog extends Animal {
    public Dog(int ageInt){
        super(ageInt);
    }
    public void move() {
        System.out.println("狗可以跑和走");
    }

    public void bark() {
        System.out.println("狗可以吠叫");
    }
}

class Main {
    public static > void mySort1(List list){
        Collections.sort(list);
    }
    public static > void mySort2(List list){
        Collections.sort(list);
    }
    public static void main(String[] args) {
        List animals = new ArrayList<>();
        animals.add(new Animal(2));
        animals.add(new Animal(1));

        mySort1(animals);
        mySort2(animals);

        List dogs = new ArrayList<>();
        dogs.add(new Dog(4));
        dogs.add(new Dog(3));

        mySort1(dogs);
        mySort2(dogs);
    }
}

好,如果执行这段代码java就会稳稳的报错了.

错误: 无法将类 Main中的方法 mySort1应用到给定类型;
需要: List
找到: List
原因: 推断类型不符合上限
推断: Dog
上限: Comparable
其中, T是类型变量:
T扩展已在方法 mySort1(List)中声明的Comparable

可以看到,虽然Dog继承了Animal,并且它的父类实现了Comparable接口,然而并不可以通过编译,所以我们得到一个答案
>这种声明泛型变量的方式,要求当前类本类必须实现接口,无关父类.
>而这种方式可以通过编译,那么显然它比第一种方式更加灵活,只要它的父类实现了接口,那么它作为泛型入参也是可以满足条件的.


根据上面的小demo可以得出结论:
第一种写法简单但限制必须是当前类实现接口不够灵活,
第二种方法会查找根据继承关系去查找是否有父类实现过接口,有即满足泛型入参要求.更加灵活

大家可以根据具体场景选用泛型变量的声明方式

你可能感兴趣的:(Java随笔-泛型)