IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Java类型擦除 -> 正文阅读

[移动开发]Java类型擦除

什么是类型擦除

Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除。Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。

问1:Java类型擦除是什么过程出现的?

Java泛型编译过程会擦除掉泛型信息。

    /**
     * 比较两个ArrayList的类型比较
     * 1) 第一个ArrayList是ArrayList<String>,第二个是ArrayList<Integer>
     *  实际运行时获取的类型都是java.util.ArrayList
     *
     * @author zhouronghua
     * @time 2022/1/10 4:15 下午
     */
    @Test
    public void testGenericTypeCompare() {
        System.out.println("测试泛型类比较");
        // 第一个是字符串ArrayList
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("One");
        list1.add("Two");
        // 第二个是整形ArrayList
        ArrayList<Integer> list2 = new ArrayList<>();
        list2.add(100);
        list2.add(200);
        // 比较两个ArrayList类型
        System.out.println("ArrayList Type compare: " + (list1.getClass() == list2.getClass()));
        // java.util.ArrayList
        System.out.println("ArrayList<String> Type: " + list1.getClass());
        // java.util.ArrayList
        System.out.println("ArrayList<Integer> Type: " + list2.getClass());
    }

编译后的类型进行了擦除,都是ArrayList,限定类型都已经擦除了。

我们通过查看字节码,就可以清晰的看到ArrayList的类型限定擦除了。添加元素的时候,

对象类型使用的是Object

2.类型擦除后保留的原始类型?

原始类型?就是擦除去了泛型信息,最后在字节码中的类型变量的真正类型,无论何时定义一个泛型,相应的原始类型都会被自动提供,类型变量擦除,并使用其限定类型(无限定的变量用Object)替换。

问2:是否能够通过instanceof查询ArrayList的类限定类型(泛型信息)?

不能。

2.Java协变和逆变

因为泛型类型编译过程中会发生类型擦除,那么怎么将子类的发行模板的对象,传递给父类的泛型模板使用。

例如:Integer集成Number,根据里氏替代原则:

Number number = new Integer(100);

对象创建的时候,可以直接将Integer对象赋值给number。

如果泛型中也希望达到这种效果,将子类的泛型赋值给父类泛型使用,怎么处理呢?可以通过通配符进行类型限定,从而实现协变

// 采用通配符实现协变
ArrayList<? extends Number> list1 = new ArrayList<Integer>();

协变:将父类保持了子类型的继承关系。通过协变实现子类型的泛型类型可以赋值给父类型泛型。

逆变:逆转了子类型的关系。将父类型泛型赋值给子类型泛型。

不变:两种关系都不满足

3.Java逆变

怎么将ArrayList<Number>赋值给ArrayList<Integer>呢?

通过? super实现逆变

ArrayList<? super Integer> list2 = new ArrayList<Number>();

参考文案:
Java泛型中的类型擦除详解 - 知乎

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-12 00:07:14  更:2022-01-12 00:09:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:32:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码