Java泛型是JDK 5引入的一个特性,它允许我们定义类和接口的时候使用参数类型,泛型在集合框架中被广泛使用。类型擦除是泛型中最让人困惑的部分,本篇文章将阐明什么是类型擦除,以及如何使用它。

一个常见错误

package simplejava;

import java.util.ArrayList;

public class Q29 {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("a");
al.add("b");
accept(al);
} public static void accept(ArrayList<Object> al) {
for (Object o : al)
System.out.println(o);
} }

以上代码看起来是没问题的,因为String是Object的子类。然而,这并不会工作,编译不会通过,并提示如下错误:
The method accept(ArrayList<Object>) in the type Q29 is not applicable for the arguments (ArrayList<String>)

List<Object>和List<String>

原因在于类型擦除。记住:Java的泛型机制是在编译级别实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息。

在编译之后,List<Object>和List<String>将变成List,Object和String类型信息对于JVM来说是不可见的。在编译阶段,编译器发现它们不一致,因此给出了一个编译错误。

通配符和有界通配符

List<? >表示List能包含任何类型的元素

    public static void main(String args[]) {
ArrayList<Object> al = new ArrayList<Object>();
al.add("abc");
test(al);
} public static void test(ArrayList<?> al) {
for (Object e : al) {// no matter what type, it will be Object
System.out.println(e);
// in this method, because we don’t know what type ? is, we can not
// add anything to al.
}
}

永远记住,泛型是一个编译时的概念。在这个例子中,由于我们不知道?,我们不能添加任何元素到al集合。如果想要添加的话,可以使用通配符。

List< Object > - List can contain Object or it’s subtype
List< ? extends Number > - List can contain Number or its subtypes.
List< ? super Number > - List can contain Number or its supertypes.

与数组比较

现在,我们知道了ArrayList <String >并不是ArrayList <Object >的子类型,不过,你需要知道如果两个泛型类型有相同的参数,它们的继承关系是依据其类型。如ArrayList<String>是Collecton<String>的子类型。

然而,数组却不同,它们在运行期间知道每个元素的类型且强制它们的元素为该类型,这叫reification。举个例子,Object[] objArray是String[] strArr的超类型。如果你尝试往存储整型的数组添加字符串对象,将会在运行期间得到一个ArrayStoreException异常。

译文链接:http://www.programcreek.com/2011/12/java-type-erasure-mechanism-example/

Java类型擦除机制的更多相关文章

  1. 初探Java类型擦除

    本篇博客主要介绍了Java类型擦除的定义,详细的介绍了类型擦除在Java中所出现的场景. 1. 什么是类型擦除 为了让你们快速的对类型擦除有一个印象,首先举一个很简单也很经典的例子. // 指定泛型为 ...

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

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

  3. JAVA类型擦除

    Java泛型-类型擦除 一.概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Num ...

  4. Java中泛型 类型擦除

    转自:Java中泛型是类型擦除的 Java 泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,但有一点需要注意:Java 的泛型在编译器有效,在运行期被删除,也就是说所有泛型参数类 ...

  5. Java 泛型 四 基本用法与类型擦除

    简介 Java 在 1.5 引入了泛型机制,泛型本质是参数化类型,也就是说变量的类型是一个参数,在使用时再指定为具体类型.泛型可以用于类.接口.方法,通过使用泛型可以使代码更简单.安全.然而 Java ...

  6. Java的反射机制和动态代理

    介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大的功能,可以原 ...

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

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

  8. Java泛型类与类型擦除

    转载自:http://blog.csdn.net/lonelyroamer/article/details/7868820 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型. ...

  9. java泛型 8 泛型的内部原理:类型擦除以及类型擦除带来的问题

    参考:java核心技术 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首 ...

随机推荐

  1. 根据日期查询access数据库

    获取指定日期的记录 1.select Field1 from  A  where format("yyyy-MM-dd",Field1)=#2011-10-07# 有时不能获取记录 ...

  2. js或css文件合并的三种方式推荐

    源文档 <http://www.jb51.net/article/32834.htm> 在Web项目的开发中,js,css文件会随着项目的开发变得越来越多,越来越大,这就给给性能方面带来一 ...

  3. 【C#】让工具栏ToolStrip能触发焦点控件的Leave、Validating、DataError等事件以验证数据

    ----------------更新:2014-04-21--------------- 蒙doggo兄指教,得知有更好的方法可以代替蹩脚的0尺寸Button法,即调用窗体的验证方法Form.Vali ...

  4. 导出Excel文件(针对Dev)

    文件类: using System;using System.Collections.Generic;using System.Linq;using System.Text;using System. ...

  5. javamail 利用qq邮箱做邮箱服务器,简单小demo

    首先maven: <dependency> <groupId>javax.mail</groupId> <artifactId>mail</art ...

  6. 2016 年青岛网络赛---Family View(AC自动机)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5880 Problem Description Steam is a digital distribut ...

  7. Java--简单的Spring AOP配置以及AOP事物管理,JDK/GCLib动态代理

    一.看一下简单的通过XML的AOP配置 1.首先创建一个简单的Student类 public class Student { private Integer age; private String n ...

  8. 小白linux安装php 5.6+nginx配置(踩坑版)

    因为要搭建个知识库,直接用wordpress,这前提是得先装php,实在不喜欢XAMPP,所以自己折腾,没想到php这一来还不少啊,从头到尾折腾了一个小时多.记录下主要的流程和遇到的坑. 首先官网下载 ...

  9. AWS CloudFront CDN直接全站加速折腾记The request could not be satisfied. Bad request

    ERROR The request could not be satisfied. Bad request. Generated by cloudfront (CloudFront) Request ...

  10. 使用coding、daocloud和docker打造markdown纯静态博客

    说起独立博客的技术演变,从数据库到纯文本放git是一大进步,从HTML到markdown又是一大进步. 解析技术有没有进步呢?既然markdown是纯文本了,再用PHP/Python/Ruby去实时解 ...