泛型与类型擦除

public class K_GenricTypes {
    public static void method(List list) {
        System.out.println("method");
    }
}

编译上面的类:javac -encoding utf-8 .\K_GenricTypes.java

生成class后反编译:javap -verbose .\K_GenricTypes.class

再写一个method方法带泛型的类,然后编译此类,再反编译class

public class K_GenricTypes {
    public static void method(List<String> list) {
        System.out.println("method");
    }
}

对比下这两个类method方法反编译后的代码

泛型方法method(List<String> list)与非泛型方法method(List list)对比:

1、code属性完全一样

2、泛型方法比非泛型方法多了一个Signature属性。

因为java语言的泛型采用的是擦除法实现的伪泛型,在字节码(Code属性)中,泛型信息(类型变量、参数化类型)编译之后都通通被擦除掉。因此,对于运行期的Java语言来说,List<String>、List<Integer>是同一个类。

为了弥补擦除的不足,新增了Signature属性。Signature属性的作用是存储一个方法在字节码层面的特征签名,这个属性保存的参数类型不是原生类型,而是包括了参数化类型的信息。

在运行期,也可以通过反射获取泛型的信息,示例如下:

public class K_GenricTypes {
    public static void method(List<String> list) {
        System.out.println("method");
    }
}

class K_GenricTypesMain {

    public static void main(String[] args) throws Exception{
        Method method = K_GenricTypes.class.getMethod("method",List.class);
        Type[] types = method.getGenericParameterTypes();
        for (Type type : types) {
            System.out.println("参数类型:"+type);
            //参数类型:java.util.List<java.lang.String>
            if(type instanceof ParameterizedType){
                Type[] paramType = ((ParameterizedType) type).getActualTypeArguments();
                for (Type t : paramType) {
                    System.out.println("泛型类型:"+t);
                    //泛型类型:class java.lang.String
                }
            }
        }

    }
}
发布了51 篇原创文章 · 获赞 14 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u010606397/article/details/82928438