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

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. asp.net core结合Gitlab-CI实现自动化部署

    0.目录 整体架构目录:ASP.NET Core分布式项目实战-目录 一.前言 在之前的文章中写过k8s+Jenkins+GitLab-自动化部署asp.net core项目 的topic,这次讲解一 ...

  2. java getenv getProperties区别

    网上很多使用的是getProperties.说获得系统变量,但是其实不正确.getProperties中所谓的"system properties"其实是指"java s ...

  3. 初识Linux 基础操作(2)

    1.Linux启动流程    1).linux启动过程        ①.进入grub界面选择相应的启动内核        ②.读取kernel内核文件-/boot/vmlinuz-*         ...

  4. 【9.23校内测试】【抽屉原理】【乱搞??(找众数】【Trie】

    看到题目一开始想到的是一道求子集和的异或和,可以用$bitset$实现求子集和.然而这道题如果要强算子集和肯定是带不动的,况且还要算方案,所以尝试去找题目中的性质. 看到整除,很容易想到如果是一段区间 ...

  5. BZOJ1002輪狀病毒 暴搜 + 找規律 + 高精度

    @[暴搜, 找規律, 高精度] Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个\(n\)轮状基由圆环上\(n\)个不同的基原子和圆心处一个核原子构成的,2个 ...

  6. servlet中请求转发(forword)和重定向(redirect)的区别

    servlet请求转发与重定向的区别: request.setAttribute("test","hello"); request.getRequestDisp ...

  7. Codeforces Round #348 (VK Cup 2016 Round 2, Div. 1 Edition) C. Little Artem and Random Variable 数学

    C. Little Artem and Random Variable 题目连接: http://www.codeforces.com/contest/668/problem/C Descriptio ...

  8. linux基础命令学习(五)目录或文件权限

    一.查看文件的详情 ls -al 二.改变目录或文件的权限 chmod [-cfvR] [--help] [--version] mode file 1. 必要参数 -c 当发生改变时,报告处理信息 ...

  9. git中:关于origin和master

    git的服务器端(remote)端包含多个repository,每个repository可以理解为一个项目.而每个repository下有多个branch."origin"就是指向 ...

  10. oc/object-c/ios用int还是NSInteger

    当需要使用int类型的变量的时候,可以像写C的程序一样,用int,也可以用NSInteger,但更推荐使用NSInteger,因为这样就不用考虑设备是32位的还是64位的. 可以看如下定义:#if _ ...