泛型类简单理解
2020-10-19
·
hexer

泛型类

疯狂java讲义中,给出了下面这个例子来描述泛型类

//定义Apple时使用了泛型声明
public class Apple<T> {
    //使用T定义实例变量
    private T info;
    public Apple(){}

    public Apple(T info) {
        this.info = info;
    }

    public T getInfo() {
        return info;
    }

    public void setInfo(T info) {
        this.info = info;
    }

    public static void main(String[] args) {
        //由于传给T形参的是String,所以构造器参数只能是String
        Apple<String> a1 = new Apple<>("苹果");
        System.out.println(a1.getInfo());
        //由于传给T形参的是Double,所以构造器参数只能是Double或double
        Apple<Double> a2 = new Apple<>(5.23);
        System.out.println(a2.getInfo());
    }
}

泛型,简单来讲就是规定类型,在集合中用的比较多,但我们也可以用泛型定义类或者接口甚至方法

泛型类,可以看成是有类型的类

这个类型(泛型形参)可以是自定义的,可以是String,可以是Integer,但是不能是int,double等基本数据类型,有时候,自定义的类型甚至可能是无意义的 这个泛型形参,可以被赋值,就像代码中的 Apple<String> a1 = new Apple<>("苹果");Apple<Double> a2 = new Apple<>(5.23);

T就像是我们的int a中的a,但是实际使用的时候,需要赋值,像例子中赋值的String和Double(不能是double)

还有一个,书上的原话

当创建带泛型声明的自定义类,为该类定义构造器时,构造器名还是原来的类名,不要增加泛型声明。例如为Apple<T>类定义构造器,其构造器名依然是Apple,而不是Apple<T>,但调用该构造器时却可以使用Apple<T>的形式,当然应该为T形参传入实示的类型参數。

这个的话看一下原来的示例代码就明白了

public Apple(T info) {//构造器,没有<>
    this.info = info;
}
Apple<String> a1 = new Apple<>("苹果");//调用的时候可以使用<>

泛型类派生子类

带有泛型声明的接口或者类,创建子类的时候,不能再包含类型形参,而是具体的类型 例如

public class A extends Apple<T>()//错误
public class A extends Apple<String>()//正确

书上说,使用方法时必须把形参给赋值,使用类时倒是不用 但是,可能是我JDK版本(13)比较高的缘故,或者IDEA优化了,使用方法时也可以不用,但是类型就是object的类型了, 或者我理解有误,还请大佬指出

public class A extends Apple{
    public static void main(String[] args) {
        A aa = new A();
        aa.setInfo("hhh");
        System.out.println(aa.getInfo());
    }
}

输出hhh

public class A extends Apple{
    public static void main(String[] args) {
        A aa = new A();
        aa.setInfo("hhh");
        aa.setInfo(4);
        System.out.println(aa.getInfo());
    }
}

输出4

参考: 疯狂java讲义第五版