- 浏览: 26733 次
- 性别:
- 来自: 杭州
最新评论
类型擦除(type erasure)。 Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节代码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。这个过程就称为类型擦除。如在代码中定义的List<Object>和List<String>等类型,在编译之后都会变成List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法避免在运行时刻出现类型转换异常的情况。类型擦除也是Java的泛型实现方式与C++模板机制实现方式之间的重要区别。
很多泛型的奇怪特性都与这个类型擦除的存在有关,包括:
泛型类并没有自己独有的Class类对象。比如并不存在List<String>.class或是List<Integer>.class,而只有List.class。
静态变量是被泛型类的所有实例所共享的。对于声明为MyClass<T>的类,访问其中的静态变量的方法仍然是 MyClass.myStaticVar。不管是通过new MyClass<String>还是new MyClass<Integer>创建的对象,都是共享一个静态变量。
泛型的类型参数不能用在Java异常处理的catch语句中。因为异常处理是由JVM在运行时刻来进行的。由于类型信息被擦除,JVM是无法区分两个异常类型MyException<String>和MyException<Integer>的。对于JVM来说,它们都是 MyException类型的。也就无法执行与异常对应的catch语句。
类型擦除的基本过程也比较简单,首先是找到用来替换类型参数的具体类。这个具体类一般是Object。如果指定了类型参数的上界的话,则使用这个上界。把代码中的类型参数都替换成具体的类。同时去掉出现的类型声明,即去掉<>的内容。比如T get()方法声明就变成了Object get();List<String>就变成了List。接下来就可能需要生成一些桥接方法(bridge method)。这是由于擦除了类型之后的类可能缺少某些必须的方法。比如考虑下面的代码:
class MyString implements Comparable<String> {
public int compareTo(String str) {
return 0;
}
}
当类型信息被擦除之后,上述类的声明变成了class MyString implements Comparable。但是这样的话,类MyString就会有编译错误,因为没有实现接口Comparable声明的int compareTo(Object)方法。这个时候就由编译器来动态生成这个方法。
很多泛型的奇怪特性都与这个类型擦除的存在有关,包括:
泛型类并没有自己独有的Class类对象。比如并不存在List<String>.class或是List<Integer>.class,而只有List.class。
静态变量是被泛型类的所有实例所共享的。对于声明为MyClass<T>的类,访问其中的静态变量的方法仍然是 MyClass.myStaticVar。不管是通过new MyClass<String>还是new MyClass<Integer>创建的对象,都是共享一个静态变量。
泛型的类型参数不能用在Java异常处理的catch语句中。因为异常处理是由JVM在运行时刻来进行的。由于类型信息被擦除,JVM是无法区分两个异常类型MyException<String>和MyException<Integer>的。对于JVM来说,它们都是 MyException类型的。也就无法执行与异常对应的catch语句。
类型擦除的基本过程也比较简单,首先是找到用来替换类型参数的具体类。这个具体类一般是Object。如果指定了类型参数的上界的话,则使用这个上界。把代码中的类型参数都替换成具体的类。同时去掉出现的类型声明,即去掉<>的内容。比如T get()方法声明就变成了Object get();List<String>就变成了List。接下来就可能需要生成一些桥接方法(bridge method)。这是由于擦除了类型之后的类可能缺少某些必须的方法。比如考虑下面的代码:
class MyString implements Comparable<String> {
public int compareTo(String str) {
return 0;
}
}
当类型信息被擦除之后,上述类的声明变成了class MyString implements Comparable。但是这样的话,类MyString就会有编译错误,因为没有实现接口Comparable声明的int compareTo(Object)方法。这个时候就由编译器来动态生成这个方法。
发表评论
-
spring bean初始化
2015-05-20 17:51 4841.配置文件中每一个<bean>解析成一个Bean ... -
java 基本类型存储解析
2012-07-11 12:53 995byte b=-128; byte b=127; 都是可以编 ... -
nio
2012-01-31 16:57 809原来的I/O包和NIO处理数据最大的不同之处在于数据打 ... -
null
2012-01-30 17:34 559null可以转换成任何类的对象 -
java 线程的几个方法
2012-01-17 15:39 997Thread的方法 sleep() 1. sleep ()函 ... -
java 线程
2012-01-17 14:37 737现在的系统的都是分时系统,达到多进程的效果。cpu只是将时间 ... -
java 访问修饰符
2012-01-12 10:34 728对于类成员(字段和方法)的访问权限来说, public:所有类 ... -
设计模式初学
2012-01-10 17:39 687代理模式只是原来对象的一个替身(原来对象约束了代理的行为) ... -
jndi学习
2012-05-26 19:10 721jndi--命名和目录服务api 用于查找远程的资源,例如 ... -
java 泛型学习--泛型方法
2011-12-26 17:30 946通过在类的定义中添加 ... -
java 泛型学习--类型通配符
2011-12-26 17:17 890假设您具有该方法: void printList(Lis ... -
java 泛型学习
2011-12-26 16:42 770除了异常类型、枚举或匿名内部类以外,任何类都可以具有类型参数。 ... -
servlet path学习
2011-12-22 15:40 947servlet path就是取从context path后开始 ... -
log4j 学习
2011-12-16 11:01 948Log4j除了可以记录程序 ... -
java 可变长参数
2011-12-15 15:15 336[size=x-large] java 的可变长参数 例如: ... -
java垃圾回收
2011-12-12 19:16 639Java语言建立了垃圾收集机制,用以跟踪正在使用的对象和发现 ... -
velocity性能优化
2011-12-09 11:16 9471.char to byte 字符转变字节,流用字节去输出 ... -
velocity 宏
2011-12-12 19:16 11231.方法当作参数化 当使用引用作为参数传递给Velocity ... -
ThreadLocal
2011-11-10 14:48 684每个线程有一个ThreadLocalMap对象,这是一个Map ... -
struts2 Codebehind Plugin
2011-11-08 15:32 3281.为未定义的action指定mapping When no ...
相关推荐
然而,Java 的泛型在运行时是被擦除的,这意味着在运行时刻,所有的泛型类型信息都会丢失,无法直接用来创建对象或进行类型检查。这导致我们无法使用 `new T()` 或 `instanceof` 这样的操作。为了解决这个问题,我们...
本文将深入探讨Java泛型类型擦除的概念,并介绍在类型擦除后,为了保持泛型的安全性和便利性,Java设计者所采取的一些补偿机制。 1. **类型擦除**: - 在编译期间,所有的泛型类型信息都会被替换为它们的实际类型...
Java泛型机制详解 Java泛型是Java语言中的一种机制,用于在编译期检查类型安全。Java泛型的出现解决了Java早期版本中类型安全检查的缺陷。Java泛型的好处是可以在编译期检查类型安全,避免了运行时的...
然而,Java泛型的实现机制——类型擦除,也带来了一系列的问题和限制。本文将深入探讨Java泛型擦除的工作原理、它对编程的影响,以及在实际开发中的应对策略。 Java泛型的类型擦除机制是Java泛型实现的核心,它使得...
- **类型擦除**:Java泛型采用了类型擦除的策略,这意味着在编译期间,泛型信息会被删除,只留下原始的无参数类型,这解决了与Java的向下兼容问题。 - **JDK 5.0引入**:Java 5.0正式引入泛型,使得在编译时期就能...
在 Java 语言中,泛型类型擦除的机制使得开发者难以理解和使用泛型,例如,在 Java 中,我们可以定义一个泛型类 `ArrayList<T>`,其中 `T` 是类型参数,但是,在编译后的字节码文件中,泛型类型信息已经被擦除,所有...
综上所述,虽然Java泛型在编译后会进行类型擦除,但通过上述技巧,我们仍然能够在运行时获得关于泛型类实例化类型的一些信息。在实际开发中,这些方法可以帮助我们编写更加灵活和安全的代码。在示例文件`GenericRTTI...
5. **泛型擦除**:阐述Java泛型的运行时机制,即泛型信息在编译后会被擦除,因此泛型并不直接改变程序的运行时行为,但类型检查在编译阶段已完成。 6. **类型推断**:描述了Java编译器如何根据上下文自动推断类型...
"Java 泛型总结(一):基本用法与类型擦除" Java 泛型是 Java 语言中的一种强大功能,它可以使代码更加简洁、安全。下面是对 Java 泛型的基本用法和类型擦除机制的介绍。 泛型的基本用法 ------------- 泛型是...
Java泛型是Java SE 5.0引入的一个重要特性,它极大地增强了代码的类型安全性和可读性。泛型在编程中的应用广泛,特别是在集合框架中,使得我们可以在编译时就检查类型,避免了不必要的类型转换,并且提高了代码的...
8. 类型擦除(Type Erasure):Java的泛型在实现时使用了类型擦除技术,这意味着泛型类型信息在编译后不会存在于JVM字节码中。这个机制有其优点也有缺点,优点是兼容旧版Java代码,缺点是无法实现泛型数组等特性。 ...
Java泛型是Java编程语言中的一个强大特性,它允许我们在定义类、接口和方法时指定类型参数,从而实现代码的重用和类型安全。在Java泛型应用实例中,我们可以看到泛型如何帮助我们提高代码的灵活性和效率,减少运行时...
Java泛型在编译后会进行类型擦除,也就是说,所有的泛型信息在运行时都会消失。因此,虽然在编译期间我们能获得类型检查的好处,但在运行时,泛型接口和类的行为与无参数类型版本基本相同。 5. **通配符** 在某些...
Java泛型是Java编程语言中一个强大的特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。泛型的主要目标是提高代码的类型安全性和重用性,减少类型转换的麻烦,并在编译时捕获可能的类型错误。...
- **类型擦除**:Java泛型在编译后会被类型擦除,所有类型参数都会被替换为它们的边界类型或者Object,因此在运行时没有泛型的概念,这是为了保持向后兼容性。 3. **泛型的优势** - **类型安全**:编译时就能发现...
1. **类型擦除**:Java泛型的主要特点是类型擦除。这意味着在编译完成后,所有的泛型信息都会被擦除,替换为Object或者其他基础类型。因此,泛型在运行时并不存在,所有关于泛型的操作都在编译期间完成。 2. **边界...