【数据结构】泛型

目录

一、泛型的引入

二、泛型类的使用

2.1语法

2.2泛型方法

2.3泛型的注意点

2.4 类型擦除


泛型是JDK1.5引入的新特性,适用于很多类型。

一、泛型的引入

public class Pointer {
    private Object x;
    private Object y;
    public Object getX() {
        return x;
    }
    public void setX(Object x) {
        this.x = x;
    }
    public Object getY() {
        return y;
    }
    public void setY(Object y) {
        this.y = y;
    }
    public static void main(String[] args) {
        Pointer p1 = new Pointer();
        p1.setX(10);
        p1.setY(20);
        int x1 = (int)p2.getX();
        int y1 = (int)p2.getY();
        System.out.println("x = "+x1+", y = "+y1);
        p2.setX("东经108度");
        p2.setY("23");
        int x = (int)p2.getX();
        int y = (int)p2.getY();
        System.out.println("x = " + x + ",y = " + y);
    }
}

 由于Object虽然可以接收所有类型,但是Object转为其他类型都需要进行强制类型转换。调用getX和getY方法时,需要根据具体的类型,将Object强转为具体的子类(隐藏的风险,这个风险是发生在运行阶段的)。

像上述代码,p1可以进行强类型转换,但是p2就不可以,并且还会在运行阶段报出。

 需要有一种新的机制,可以在定义类时,成员变量可以接收多种类型,但是在具体产生对象时明确类型,当有不同类型设置时,编译阶段就能发现错误。

所谓的泛型就是在我们定义类和方法时,没有明确参数的类型,而是在使用该类时,明确类型,不需要进行类型强转,编译阶段就会在语法阶段检查类型是否匹配的机制。类型的编译阶段守门员,不会让类型不匹配的问题进入到运行阶段。

二、泛型类的使用

泛型和Object最大的区别在于,Object转为其他类型都需要强制转换,只要强转都有类型转换出错的风险,泛型的出现就是为了解决该问题,有泛型不需要进行类型转换,编译阶段就可以校验设置的类型是否是产生对象时的类型。

2.1语法

类名称<类型参数>{ 类型参数 成员变量名称;……}

类型参数一般都用单个大写字母代替。只是一个指代。

根据泛型类,来产生泛型对象。泛型类定义时,可以不明确成员类型的变量,但是在产生对象时,必须明确类型。

泛型类<明确类型>  引用类型 = new 泛型类名称<>();

public class Point<T> {
    private T x;
    private T y;
    public T getX() {
        return x;
    }
    public void setX(T x) {
        this.x = x;
    }
    public T getY() {
        return y;
    }
    public void setY(T y) {
        this.y = y;
    }
    public static void main(String[] args) {
        Point<Integer> p = new Point<>();
        p.setX(10);
        p.setY(20);
        int m = p.getX();
        int n = p.getY();
        System.out.println("x = "+ m +",y = "+ n);
    }
}

泛型类还可以使用多个参数类型,当上述代码中的x和y使不同类型是,可以使用多个类型参数。

T=> 一般指代任何类均可。

E=> 一般代表元素ELement和T意义差不多,也有使用E来指代异常的意思。

K和V一般搭配使用,描述一个键值对的对象,K=> key的意思,不重复的键值,V=> value的意思,可以重复。

2.2泛型方法

泛型不仅可以定义类,还可以单独定义方法。

public class Point<T> {
    public <E> void fun(E t){
        System.out.println("泛型方法fun");
        System.out.println(t);
    }
    public static void main(String[] args) {
        Point<Integer> p = new Point<>();
        p.fun("123");

    }
}

泛型方法以自己的类型为基准,为了区分和泛型类的类型参数,一般若泛型类中存在泛型方法,使用不同的类型参数。

2.3泛型的注意点

1、泛型只能用在成员域,不能用在静态域static修饰的内容不能使用泛型。

2、产生泛型对象时,具体的类型不能使用基本数据类型,要使用基本数据类型的包装类。

3、不能直接创建和实例化泛型数组,要使用泛型数组,统一使用Object数组。

进入JVM之后没有泛型相关的信息,new在运行阶段JVM开辟空间,JVM不认识泛型类,所以不能创建和实例化。

正确使用泛型数组的方式:

要使用泛型数组,统一定义为Object数组,然后在增删改查数组时使用泛型。

public class MyClass<E> {
    private E e;
    private Object[] value = new Object[10];
    int size = 0;
    private void add(E e){
        value[size] = e;
        size++;
    }
    public E get(int index){
        return (E)value[index];
    }
    public static void main(String[] args) {
        MyClass<Integer> myClass = new MyClass<>();
        myClass.add(1);
        myClass.add(3);
        myClass.add(5);
        System.out.println(myClass.get(2));
    }
}

2.4 类型擦除

泛型信息只存在于编译阶段,在进入JVM之前,与泛型有关的所有信息会被编译器擦除掉,专业术语称为类型擦除。

public class MyClass<T,E> {
    private T t;
    private E e;
    public static void main(String[] args) {
        MyClass<Integer,String> myClass = new MyClass<>();
        Class cls = myClass.getClass();
        // 通过反射获取MyClass的所有属性,反射都是在运行阶段生效
        Field[] fields = cls.getDeclaredFields();
        for (Field field : fields) {
            // 输出该属性对应的类型
            System.out.println(field.getType());
        }

    }
}

利用反射返回属性的类型,输出的是Object类,所以泛型类已经在编译时擦除了。 一般的泛型都会擦除为Object类,若泛型存在上限,擦除为对应的泛上限。

 

  • 18
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世界级白日梦冠军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值