这一章节我们继续类型擦除的话题,我们将通过对照数组与泛型容器,观察类型擦除给泛型容器带来什么问题?

1.数组

package com.ray.ch13;

public class Test {

	public static void main(String[] args) {
Fruit[] fruits = new Apple[5];
fruits[0] = new Apple();
fruits[1] = new Fuji();
fruits[2] = new Fruit();
}
} class Fruit {
} class Apple extends Fruit {
} class Fuji extends Apple {
}

观察上面的代码,我们能够看到。尽管定义仅仅是Fruit 的数组。可是它能够放进去Apple、Fuji等子类型的对象,由于数组是持有对象的引用,并且能够在执行时向上转型。

2.泛型容器

一般使用方法:

package com.ray.ch13;

import java.util.ArrayList;

public class Test {

	public static void main(String[] args) {
ArrayList<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit());
fruits.add(new Apple());
fruits.add(new Fuji());
}
} class Fruit {
} class Apple extends Fruit {
} class Fuji extends Apple {
}

上面是我们的经常使用使用方法。定义一个List容器。泛型里面填写的是同一个类型。

可是,我们以下将依据向上转型的特性,看看能不能像数组一样?

样例:

package com.ray.ch13;

import java.util.ArrayList;

public class Test {

	public static void main(String[] args) {
// ArrayList<Fruit> fruits = new ArrayList<Apple>();//error
ArrayList<? extends Fruit> fruits = new ArrayList<Apple>();
// fruits.add(new Apple());//error
// fruits.add(new Fruit());//error
fruits.add(null);// 这里仅仅能是null,没有其它选择
}
} class Fruit {
} class Apple extends Fruit {
} class Fuji extends Apple {
}

观察上面的代码,本来我们想跟数组一样,在创建list的时候仅仅是把泛型定义为Fruit的子类,可是。编译器抛异常。

这是由于泛型不是全然定义,它仅仅是在编译器检查类型安全。在执行期就没有泛型的概念了。而当我们定义的时候是通过通配符“?”来定义,也就是说我能够放进去Fruit的本身或者子类,编译器能够知道,可是在执行期。jvm仅仅是知道放进来Object。而在创建的时候是定义了Apple子类。尽管编译器知道。可是在执行期。jvm也仅仅是知道放进来Object,这个时候在执行期就会引起类型安全的问题。因此,当我们放进去什么对象都会引起类型安全的时候,编译器仅仅能给出null这个选项,不然就必定会出现类型安全的风险。

总的来说,由于数组是全然定义,在编译器和执行期都会进行类型检測,或者说数组本身就是持有对象,而泛型容器仅仅是在编译器检查类型安全。而在执行期全是Object,仅仅是半定义。或者说泛型容器不持有对象,才导致上面所展示的问题。

总结:这一章节我们主要对照数组与泛型容器,观察类型擦除给泛型容器带来什么问题。

这一章节就到这里。谢谢。

-----------------------------------

文件夹

从头认识java-13.11 对照数组与泛型容器,观察类型擦除给泛型容器带来什么问题?的更多相关文章

  1. java为什么要用类型擦除实现泛型?--c++,java,c# 的泛型是如何实现的

    所以总结一下c++,java,c#的泛型.c++的泛型在编译时完全展开,类型精度高,共享代码差.java的泛型使用类型擦出,仅在编译时做类型检查,在运行时擦出,共享代码好,但是类型精度不行.c#的泛型 ...

  2. Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题

    在开发时,遇到了下面这条语句,不懂,然习之. private List<MyZhuiHaoDetailModel> listLottery = new ArrayList<MyZhu ...

  3. 【进阶之路】Java的类型擦除式泛型

    Java选择的泛型类型叫做类型擦除式泛型.什么是类型擦除式泛型呢?就是Java语言中的泛型只存在于程序源码之中,在编译后的字节码文件里,则全部泛型都会被替换为原来的原始类型(Raw Type),并且会 ...

  4. 从头认识java-14.1 再次对照数组与容器

    这一章节我们再次深入的对照数组与容器. 数组与容器主要集中在三个方面:效率.类型.基础类型. 我们能够从三方面做出对照. 1.效率 这里的下来是指add和get 的速度 以下以add为例: packa ...

  5. JAVA泛型中的类型擦除及为什么不支持泛型数组

    一,数组的协变性(covariant array type)及集合的非协变性 设有Circle类和Square类继承自Shape类. 关于数组的协变性,看代码: public static doubl ...

  6. Java泛型-内部原理: 类型擦除以及类型擦除带来的问题

    一:Java泛型的实现方法:类型擦除 大家都知道,Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除.Java的泛型基本上都是在编译 ...

  7. java泛型总结(类型擦除、伪泛型、陷阱)

    JDK1.5开始实现了对泛型的支持,但是java对泛型支持的底层实现采用的是类型擦除的方式,这是一种伪泛型.这种实现方式虽然可用但有其缺陷. <Thinking in Java>的作者 B ...

  8. Java泛型中的类型擦除机制简单理解

    Java的泛型是JDK1.5时引入的.下面只是简单的介绍,不做深入的分析. Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首 ...

  9. java基础5 (一维)数组和二维数组

    本文知识点(目录): 一维数组(一维数组的概念.优点.格式.定义.初始化.遍历.常见异常.内存分析以及常见操作(找最大值.选择排序.冒泡排序等等))    二维数组(二维数组的遍历.排序.查找.定义. ...

随机推荐

  1. shell kill session

    ps -ef | grep java kill -9 pid

  2. NetBIOS主机名扫描工具nbtscan

    NetBIOS主机名扫描工具nbtscan   NetBIOS主机名是NetBIOS协议为主机分配的名称.通过NetBIOS主机名,系统可以利用WINS服务.广播及Lmhost文件等多种模式将NetB ...

  3. Beaglebone Black开发板安装驱动

    Beaglebone Black开发板安装驱动 Beaglebone Black开发板安装驱动,在使用Beaglebone Black开发板子做任何事情之前首先需要安装驱动.下面的内容就了展示在Win ...

  4. 选择器(UIPickerView)

    Apple提供了两种形式的选择器:日期选择器(UIDatePicker)与自定义选择器(UIPickerView). 当用户使用日期选择器选定一个时间后,调用datePickerID.date可以直接 ...

  5. [BZOJ4320][ShangHai2006]Homework(根号分治+并查集)

    对于<=sqrt(300000)的询问,对每个模数直接记录结果,每次加入新数时暴力更新每个模数的结果. 对于>sqrt(300000)的询问,枚举倍数,每次查询大于等于这个倍数的最小数是多 ...

  6. AHOI2018训练日程(3.10~4.12)

    (总计:共90题) 3.10~3.16:17题 3.17~3.23:6题 3.24~3.30:17题 3.31~4.6:21题 4.7~4.12:29题 ZJOI&&FJOI(6题) ...

  7. Codeforces Beta Round #7 C. Line Exgcd

    C. Line 题目连接: http://www.codeforces.com/contest/7/problem/C Description A line on the plane is descr ...

  8. hdu 5234 Happy birthday 背包 dp

    Happy birthday Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...

  9. linux基础命令学习(四)用户与群组

    一.linux用户账号的管理 linux用户账号的管理主要包括用户添加.用户删除.用户修改. 添加用户账号就是在系统创建一个新账号,然后为新账号分为用户号.用户组.主目录和登录Shell等资源. 刚添 ...

  10. 转:IntelliJ IDEA 2016.1.3注册破解激活

    IntelliJ IDEA 2016.1.3下载地址 https://download.jetbrains.8686c.com/idea/ideaIU-2016.1.3.exe 用注册码激活: 激活码 ...