`
minfree
  • 浏览: 34880 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

java泛型字节码分析

    博客分类:
  • java
阅读更多

java泛型


   从jdk1.5开始,java语言加入了泛型支持,泛型是一种编译时的约束,可以在编译阶段确定数据的类型。泛型是在 Java 平台上作为编译时转换实现的。编译器实际上生成与使用非泛型源代码时相同的字节指令,插入运行时类型转换以在每次访问时将值转换为正确的类型。尽管是相同的字节码,但是类型参数信息用 一个新的签名(signature) 属性记录在类模式中。JVM 在装载类时记录这个签名信息,并在运行时通过反射使它可用。


字节码分析

 

非泛型类

public class Box {

    private Object object;

    public void add(Object object) {

        this.object = object;
    }

    public Object get() {
        return object;

    }
}

class 字节码信息
this class :Box
super class: Object

Fileds:
<Ljava/lang/Object;>

Methods:
add : <Ljava/lang/Object;()V>
get : <()Ljava/lang/Object;>

 


泛型类

 

public class Box<T> {

    private T t; // T stands for "Type"

    public void add(T t) {
        this.t = t;
    }


    public T get() {
        return t;
    }
}


class 字节码信息


this class :Box

[0] Signature <T:<Ljava/lang/Object;><Ljava/lang/Object;>>
super class: Object


Fileds:

<Ljava/lang/Object;>
[0] Signature <TT;>

Methods:
add : <Ljava/lang/Object;()V>
[1] Signature <TT()V;>
get : <()Ljava/lang/Object;>
[1] Signature <()TT;> 

  通过查看字节码可以发现带泛型的类和不带泛型类只在Signature部分有区别。如上TT表明类使用泛型,泛型参数名称为T。

 

方法和构造函数范围泛型

 

  泛型可以在方法或构造函数范围内声明,如下所示。它只在其声明的函数范围内有效。

public <U> void inspect(U u){

        System.out.println("T: " + t.getClass().getName());
        System.out.println("U: " + u.getClass().getName());
    }


方法信息:


inspet : <Ljava/lang/Object;()V>
[1] Signature <<U:Ljava/lang/Object;>(TU)V;>

 



 限定范围类型参数

 

public <U extends Number> void inspect(U u) {

        System.out.println("T: " + t.getClass().getName());
        System.out.println("U: " + u.getClass().getName());

    }

 


方法信息:
inspet : <Ljava/lang/Number;()V>
[1] Signature <<U:Ljava/lang/Number;>(TU)V;>

还可以增加要实现的接口限制,如下:

    public <U extends Number & Serializable> void inspect(U u) {

        System.out.println("T: " + t.getClass().getName());
        System.out.println("U: " + u.getClass().getName());

    }


方法信息:
inspet : <Ljava/lang/Number;()V>
[1] Signature <<U:Ljava/lang/Number;Ljava/lang/Serializable;>(TU)V;>

 

泛型信息擦除

 

类型参数在编译的时候会被擦除,只保留不带类型参数的raw type,因此无法再运行上下文中使用泛型类型。如下面这段代码,编译时无法通过的。

public class MyClass<E> {

    public static void myMethod(Object item) {
        if (item instanceof E) {  //Compiler error
            ...
        }

        E item2 = new E();   //Compiler error
        E[] iArray = new E[10]; //Compiler error
        E obj = (E)new Object(); //Unchecked cast warning
    }

所以泛型参数只能出现在类,方法,属性的声明中。



分享到:
评论

相关推荐

    Java-Edge#Java-Interview-Tutorial#Java语法糖之泛型与类型擦除1

    - 泛型擦除前的例子把这段Java代码编译成Class文件,然后再用字节码反编译后,將会发现泛型都不见了,又变回了Java泛型出现之前的写法,泛型类型都变回了原

    Java理论与实践:在JDK早期版本中使用Java 5的语言特性

    本文介绍了Java 5中添加的...javac中不支持的-target jsr14选项可以为某些Java 5语言特性生成与JDK 1.4兼容的字节码,并且开源的Retroweaver和Retrotranslator项目能把多数Java 5字节码转换成与Java 1.4兼容的字节码。

    泛型擦除(Generic erase)(教学视频+源代码)

    泛型擦除不是泛型丢失了,而是在编译后的字节码文件中使用单独的标识来存储泛型了。 为什么会出现泛型擦除,主要是为了编译器的兼容性。 因为在jdk5之前是没有泛型的,jdk5之后出现了泛型。 为了编译器的兼容性...

    JAVA核心知识点整理.zip

    JVM 是可运行 Java 代码的假想计算机 ,包括一套字节码指令集、一组寄存器、一个栈、 一个垃圾回收,堆 和 一个存储方法域。JVM 是运行在操作系统之上的,它与硬件没有直接 的交互。 3. JAVA 集合 集合类存放于 ...

    java深度历险

    java字节码 java类加载 java线程 java垃圾回收 java泛型 java注解 java反射与动态代理 javaI/O java安全 java对象序列化

    java手册中英文java8,java9手册

    它首先将源代码编译成字节码,再依赖各种不同平台上的虚拟机来解释执行字节码,从而具有“一次编写,到处运行”的跨平台特性。在早期JVM中,这在一定程度上降低了Java程序的运行效率。但在J2SE1.4.2发布后,Java的...

    java深度历险 InfoQ中文站

    java深度历险 InfoQ中文站 1、java字节码操作 2、java类的加载、链接和初始化 3、java线程 4、java垃圾回收机制与引用类型 5、java泛型 6、java注解 7、java反射与动态代理 8、javaI/O 9、java安全 10、java对象序列...

    java开源包8

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    JAVA上百实例源码以及开源项目

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    JAVA上百实例源码以及开源项目源代码

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    基于java的电子相册源码.zip

    这些源代码可以被Java编译器编译成字节码,然后在Java虚拟机(JVM)上运行。Java是一种面向对象的编程语言,广泛应用于各种应用场景,从桌面应用到大型企业级应用,从移动应用到嵌入式系统。 适合人群:大学生、...

    基于java的日记本源码.zip

    这些源代码可以被Java编译器编译成字节码,然后在Java虚拟机(JVM)上运行。Java是一种面向对象的编程语言,广泛应用于各种应用场景,从桌面应用到大型企业级应用,从移动应用到嵌入式系统。 适合人群:大学生、...

    基于java的考勤管理系统源码.zip

    这些源代码可以被Java编译器编译成字节码,然后在Java虚拟机(JVM)上运行。Java是一种面向对象的编程语言,广泛应用于各种应用场景,从桌面应用到大型企业级应用,从移动应用到嵌入式系统。 适合人群:大学生、...

    基于java的SSM商城系统源码.zip

    这些源代码可以被Java编译器编译成字节码,然后在Java虚拟机(JVM)上运行。Java是一种面向对象的编程语言,广泛应用于各种应用场景,从桌面应用到大型企业级应用,从移动应用到嵌入式系统。 适合人群:大学生、...

    基于java的物流信息网源码.zip

    这些源代码可以被Java编译器编译成字节码,然后在Java虚拟机(JVM)上运行。Java是一种面向对象的编程语言,广泛应用于各种应用场景,从桌面应用到大型企业级应用,从移动应用到嵌入式系统。 适合人群:大学生、...

    基于java的超市管理系统源码.zip

    这些源代码可以被Java编译器编译成字节码,然后在Java虚拟机(JVM)上运行。Java是一种面向对象的编程语言,广泛应用于各种应用场景,从桌面应用到大型企业级应用,从移动应用到嵌入式系统。 适合人群:大学生、...

Global site tag (gtag.js) - Google Analytics