跟王老师学泛型(八):泛型擦除与转换

泛型擦除与转换

主讲教师:王少华 QQ群:483773664

学习目标:

  1. 掌握泛型擦除的含义
  2. 理解泛型转换的规则

一、泛型擦除

(一)什么泛型擦除

Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。也就是说虚拟机中没有泛型,只有普通类和普通方法

使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。

类型擦除的主要过程如下:
     1.将所有的泛型参数用其最左边界(最顶级的父类型)类型替换。
     2.移除所有的类型参数。

如在代码中定义的List<object>和List<String>等类型,在编译后都会编程List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。


1

2

3

4

5

6

7

8

9

public class Test {

    public static void main(String[] args) {

        ArrayList<String> arrayList1 = new ArrayList<String>();

        arrayList1.add("abc");

        ArrayList<Integer> arrayList2 = new ArrayList<Integer>();

        arrayList2.add(123);

        System.out.println(arrayList1.getClass() == arrayList2.getClass());

    }

}

在这个例子中,我们定义了两个ArrayList数组,不过一个是ArrayList<String>泛型类型,只能存储字符串。一个是ArrayList<Integer>泛型类型,只能存储整形。最后,我们通过arrayList1对象和arrayList2对象的getClass方法获取它们的类的信息,最后发现结果为true。说明泛型类型String和Integer都被擦除掉了,只剩下了原始类型。

(二)类型擦除带来的问题

正是由于类型擦除的隐蔽存在,直接导致了众多的泛型灵异问题。

1、不能通过泛型类的实例区分方法签名,以实现方法重载

2、不能catch中使用泛型

3、泛型类的静态变量是共享的


1

2

3

4

5

6

7

8

9

10

public class Test {

    public static void main(String[] args) {

        ErasureTest<Integer> gti = new ErasureTest<Integer>();

        gti.var=1;

        ErasureTest<String> gts = new ErasureTest<String>();

        gts.var=2;

        System.out.println(gti.var);

        System.out.println(gts.var);

    }

}

(三)、避免泛型擦除

1、创建泛型对象时请指明类型

比如


1

ArrayList arrayList=new ArrayList();

改成


1

ArrayList<String>  arrayList=new ArrayList<String>();

2、下面二种写法的区别


1

2

ArrayList<String> arrayList1=new ArrayList(); //第一种 情况 

ArrayList arrayList2=new ArrayList<String>();//第二种 情况

new ArrayList()只是在内存中开辟一个存储空间,可以存储任何的类型对象。而真正涉及类型检查的是它的引用,因为我们是使用它引用arrayList1 来调用它的方法,比如说调用add()方法。所以arrayList1引用能完成泛型类型的检查。而引用arrayList2没有使用泛型,所以不行

二、泛型转换

(一)有泛型转无泛型

当把一个具有泛型信息的对象赋给另一个没有泛型信息的变量时,则所有在尖括号之间的类型信息都被扔掉了。

比如说,一个List<String>类型被转换为List,则该List对集合元素的类型检查变成了类型变量的上限(Object)


1

2

3

4

5

6

7

8

9

10

11

12

public class GenericTest2 {

    public static void main(String[] args) {

        List<Integer> li = new ArrayList<Integer>();

        li.add(6);

        li.add(9);

        Integer a = li.get(0);

        //有警告:“未经检查的转换”,编译、运行时完全正常

        List list = li;

        //元素类型被转换成Object

        Integer b = (Integer) list.get(0);

    }

}

(二)泛型A不能转泛型B

跟王老师学泛型(八):泛型擦除与转换

时间: 2024-10-12 12:12:45

跟王老师学泛型(八):泛型擦除与转换的相关文章

跟王老师学反射(八):使用反射操作数组

跟王老师学反射(八):使用反射操作数组 主讲教师:王少华   QQ群号:483773664 学习内容 使用反射操作数组 在java.lang.reflect包下还提供了一个Array类,Array对象可以代表所有的数组.程序可以通过使用Array来动态创建数组. 一.传统的创建数组的方法 1 2 3 4 5 6 7 8 public   static   void  main(String[] args)  {        int vec[] = new int[]{1, 5, 3};  //

跟王老师学注解(二)注解的分类及内建注解

跟王老师学注解(二):注解的分类及内建注解 主讲教师:王少华   QQ群号:483773664 一.注解的分类 在Java中,根据注解的使用方法和用途,可将注解分成3类,分别是 内建注解(也称为基本注解),定义于java.lang包下 元注解(Meta Annotation) 自定义注解 二.内建注解 (一)分类 在JDK5.0及以上的版本的java.lang包下提供了3种标准的注解类型,分别是 @Override: @Deprecated @SuppressWarnings (二)@Overr

跟王老师学MySQL:MySQL数据类型常见问题及解答

跟王老师学MySQL:MySQL数据类型常见问题及解答 主讲教师:王少华   QQ群号:483773664 学习内容 整数类型和浮点类型的异同 浮点数类型和定点数类型的异同 char和varchar类型的异同 时间和日期类型的异同 text和blob的异同 存储路径字符串的注意事项 mysql如何存储boolean类型 null的处理 在MySQL中创建表时,需要考虑为字段选择哪种数据类型是最合适的.选择了合适的数据类型,会提高数据库的效率. 一.整数类型和浮点类型 整数类型和浮点类型最大区别是

跟王老师学MySQL:单表查询

跟王老师学MySQL:单表查询 主讲教师:王少华   QQ群号:483773664 学习内容 查询所有字段 查询指定字段 查询指定记录 带in关键字的查询 带between and关键字的查询 带like关键字的查询 查询空值 带and的多条件查询 带or的多条件查询 查询不重复记录 对查询结果进行排序 单表查询是指从一张表中查询所需要的数据.查询数据时,可以从一张表中查询数据,也可以从多张表中同时查询数据.两者的查询方式上有一定的区别.因为单表查询只在一张表上进行操作,所以查询比较简单. 一.

跟王老师学反射(四):Class类:从Class类中获取信息

跟王老师学反射(四)Class类:从Class类中获取信息 主讲教师:王少华   QQ群号:483773664 学习内容 获得class类中的信息 根据我们以前学过的一个Java类有以下几部组成,如下代码所示 一.访问Class对应的类所包含的构造方法 (一)public Constructor<T> getConstructor(Class<?>... parameterTypes) 返回此Class对象所表示的类的指定public构造方法. parameterTypes参数是按

跟王老师学MySQL:配置MySQL

跟王老师学MySQL:配置MySQL 主讲教师:王少华   QQ群号:483773664 学习内容 学会配置免安装版的MySQL 一.配置环境变量path 测试配置是否成功 二.修改配置文件 配置文件名称:my-default.ini 路径:D:\mysql-5.7.13 设置的内容:字符编码.mysql所在目录.数据库所在目录.端口号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

跟王老师学MySQL:MySQL数据类型之小数类型

跟王老师学MySQL:MySQL数据类型之小数类型 主讲教师:王少华   QQ群号:483773664 学习内容 小数类型有哪些以及它们的取值范围 定义语法中的M和D的含义 定点型和浮点型的区别 一.简介 MySQL中使用浮点数类型和定点数类型来表示小数. 浮点数类型包括单精度浮点数(FLOAT型)和双精度浮点数(DOUBLE型). 定点数类型就是DECIMAL型. 二.字节数.取值范围 三.定义语法 1 类据类型 (M,D) M:精度,数据的总长度 D:标度,小数点后的长度 注: 小数点不占长

跟王老师学MySQL:MySQL数据类型之字符类型

跟王老师学MySQL:MySQL数据类型之字符类型 主讲教师:王少华   QQ群号:483773664 学习内容: 字符串类型的种类及其特点 char和varchar的异同 字符串类型是在数据库中存储字符串的数据类型. 字符串类型包括 CHAR. VARCHAR BLOB TEXT 一.char和varchar (一)定义语法 1 字符串类型 (M) 注: 字符串类型:char或varchar M:指定了该字符串最大长度 (二)二者不同之处 char类型长度是固定的,即在创建表时就指定了,其长度

跟王老师学MySQL:MySQL数据类型之日期与时间类型

跟王老师学MySQL:MySQL数据类型之日期与时间类型 主讲教师:王少华   QQ群号:483773664 学习内容 YEAR类型的特点及使用 TIME类型的特点及使用 DATE类型的特点及使用 DATETIME类型的特点及使用 TIMESTAMP类型的特点及使用 MySQL表示日期和时间的数据类型有以下几种: 1.YEAR类型 2.TIME类型 3.DATE类型 4.DATETIME类型 5.TIMESTAMP类型 一.Year类型 (一)简介 year使用一个字符串来表示年份 MySQL中