Java泛型

作者: 展翅高飞鹏程万里 | 来源:发表于2020-04-01 19:05 被阅读0次

本文介绍的知识点

  • 泛型是什么?
  • 泛型的使用
    • 在反射中使用泛型
    • 在集合类中使用泛型
  • 关于泛型擦除如何理解?如何避免泛型擦除带来的影响?

泛型是什么

JDK1.5增加了泛型支持在很大程度上都是为了让集合能记住其元素的类型。在没有泛型前,一旦把一个对象“丢进”java集合中,集合就忘记对象的类型,把所有的对象当成Object处理。增加了泛型支持的集合后,完全能够记住集合元素的类型,并可以在编译时检查集合中的元素类型,如何试图添加不满足类型要求的对象,编译器就会提示报错。

泛型的使用

//基本使用
List<Apple> list = new ArrayList<Apple>();
list.add(new Apple());
list.add(new Apple());
list.add(new Apple());
//并不存在泛型类
List<String> l1 = new ArrayList<>();
List<String> l2 = new ArrayList<>();
//调用getClass()方法来比l1和l2的类是否相等
System.out.println(l1.getClass() == l2.getClass());

运行上面的代码片段,可能有读者认为应该输出false,但实际输出true。因为不管泛型的实际类型参数是什么,他们在运行时总有同样的类(Class)。
注意:

java.util.Collection<String> cs = new java.util.ArrayList<>();
//下面的代码引起错误,instantceof运算符后不能使用泛型
if(cs instantceof ArrayList<String>){...}

设定类型的上&下限

//以下类的继承关系为:RedApple extends Apple extents Fruit
List<Apple> list = new ArrayList<Apple>();
        list.add(new Apple());
        list.add(new Apple());
        list.add(new Apple());

        //常用场景就是作为参数输入--拓展set方法设置数据的类型
        final List<? super RedApple> list2 = list;
        list2.add(new RedApple());
        list2.add(new RedApple());
        list2.get(0)//此处没有意义,需要知道上限的修饰符super不支持get操作就行
        //此时list集合中包含了3个类型Apple数据,2个类型RedApple数据

        //常用的场景就是作为方法返回或者成员变量输出--拓展get方法获取的类型
        final List<? extends Apple> list1 = list;
        list1.add(new Apple());//报错,不允许插入任何类型得数据
        Fruit fruit = list1.get(0);
        Apple apple = list1.get(0);

泛型方法和类型通配符的区别
定义:

public interface Collection<E>{
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extend E> c);
}

上面的程序可以使用类型通配符转换

public interface Collection<E>{
    <T> boolean containsAll(Collection<T> c);
    <T extends E> boolean addAll(Collection<T> c);
}

在反射中使用泛型

  • 有个静态方法如下,通过反射生成对象
public static Object getInstance(String clsName){
    Class cls = Class.forName(clsName);
    return cls.newInstance();
}

//比如我们用来创建Date对象的时候
Date d = (Date)getInstance("java.util.Date");//出现强转

如何避免上面创建对象的时候,对象的强转呢?将上面的静态方法改造如下:

public static <T> T getInstance(Class<T> cls){
    return cls.newInstance();
}

//比如我们创建Date对象
Date d = getInstance(Date.class);//不需要强转
  • 使用反射来获取泛型类型信息
//成员变量
Map<String,Integer> f;
Class<?> a = f.getType();//用来获取f的类型Map.class
Type gType = f.getGenericType();//获取成员变量的泛型类型<String,Integer>

//要访问泛型类型的里面的类型,方法调用如下
if(gType instanceof ParameterizedType){
    ParameterizedType pType = (ParameterizedType)gType;
    pType.getRawType();//获取原始类型 interface java.util.Map
    Type[] tArgs = pType.getActualTypeArguments();
    tArgs[0];//返回:class java.lang.String
    tArgs[1];//返回:class java.lang.Integer
}

相关文章

  • Java泛型教程

    Java泛型教程导航 Java 泛型概述 Java泛型环境设置 Java泛型通用类 Java泛型类型参数命名约定 ...

  • 第二十八课:泛型

    泛型出现之前 泛型出现之后 Java深度历险(五)——Java泛型

  • Kotlin 泛型

    说起 kotlin 的泛型,就离不开 java 的泛型,首先来看下 java 的泛型,当然比较熟悉 java 泛型...

  • java泛型中类型擦除的一些思考

    java泛型 java泛型介绍 java泛型的参数只可以代表类,不能代表个别对象。由于java泛型的类型参数之实际...

  • Java泛型

    参考:Java知识点总结(Java泛型) 自定义泛型类 自定义泛型接口 非泛型类中定义泛型方法 继承泛型类 通配符...

  • Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型

    Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型 在代码进入和离开的边界处,会处理泛型 Java泛型作...

  • JAVA 核心笔记 || [xxx] 泛型

    泛型 JAVA 的参数化类型 称为 泛型 泛型类的设计 Learn12.java 运行

  • 简单回顾Java泛型之-入门介绍

    什么时候开始有了Java泛型?什么是Java泛型?为什么要引入Java泛型?什么时候用到了泛型?可不可以给泛型下一...

  • Kotlin 泛型

    Kotlin 支持泛型, 语法和 Java 类似。例如,泛型类: 泛型函数: 类型变异 Java 的泛型中,最难理...

  • JAVA-泛型

    JAVA-泛型 sschrodinger 2018/11/15 简介 泛型是Java SE 1.5的新特性,泛型的...

网友评论

    本文标题:Java泛型

    本文链接:https://www.haomeiwen.com/subject/ixzauhtx.html