Welcome everyone

父类泛型信息为什么可以拿到?

java 汪明鑫 679浏览 0评论

泛型是一个语法糖,在编译时期会被擦除

泛型的出现减少了很多强转的操作,同时避免了很多运行时的错误,在编译期完成检查

获取当前类的泛型信息是获取不到的,获取父类的泛型信息是可以获取的到的,为什么呢?

 

package pers.wmx.springbootfreemarkerdemo;

import org.springframework.core.ResolvableType;

import java.util.HashMap;
import java.util.List;

/**
 * @author wmx
 * @date 2020-03-30
 */
public class Temp {
    public static void main(String[] args) {
        HashMap<String, List<String>> hashMap = new HashMap<>();
        ResolvableType generic0 = ResolvableType.forInstance(hashMap)
                .getGeneric(0);
        ResolvableType generic1 = ResolvableType.forInstance(hashMap)
                .getGeneric(1);
        System.out.println(generic0.getRawClass());
        System.out.println(generic1.getRawClass());

        CustHashMap custHashMap = new CustHashMap();
        ResolvableType generic00 = ResolvableType.forInstance(custHashMap)
                .getGeneric(0);
        ResolvableType generic11 = ResolvableType.forInstance(custHashMap)
                .getGeneric(1);
        System.out.println(generic00.getRawClass());
        System.out.println(generic11.getRawClass());

        ResolvableType generic00_super = ResolvableType.forInstance(custHashMap)
                .getSuperType()
                .getGeneric(0);
        ResolvableType generic11_super = ResolvableType.forInstance(custHashMap)
                .getSuperType()
                .getGeneric(1);
        System.out.println(generic00_super);
        System.out.println(generic11_super);
    }
}

class CustHashMap extends HashMap<String, List<String>> {
}

 

输出:

null
null
null
null
java.lang.String
java.util.List<java.lang.String>

 

ResolvableType 是Spring提供的一种优雅获取泛型信息的工具

根据输出结果,我们可以看出当前类泛型信息被擦除获取的是null,父类的泛型信息是可以获取的到的

 

还可以这样

 Class clazz = custHashMap.getClass();
        Type superType = clazz.getGenericSuperclass();
        if (superType instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) superType;
            Type[] actualTypes = parameterizedType.getActualTypeArguments();
            for (Type type : actualTypes) {
                System.out.println(type);
            }
        }

 

 

 

父类泛型信息存储在Signature中,常量池

 

调用到了泛型的地方会添加signature和LocalVariableTypeTable,泛型擦除不是擦除全部。
jdk提供了方法来读取泛型信息的,利用class类的getGenericSuperClass()方法我们可以在泛型类中去获取具体传入参数的类型,本质上就是通过signature和LocalVariableTypeTable来获取的。
后面找时间再看下这一块

问题来自于智翔兄弟

 

 

 

转载请注明:汪明鑫的个人博客 » 父类泛型信息为什么可以拿到?

喜欢 (0)

说点什么

您将是第一位评论人!

提醒
avatar
wpDiscuz