java 如何从泛型类中获取类型变量与字段的Map?

h43kikqp  于 11个月前  发布在  Java
关注(0)|答案(2)|浏览(127)

我有一个泛型类如下,两个类型变量,三个字段声明。

class RowClass<T1, T2> {
    public T1 t1;
    public T2 t2;
    public T1 t3;
}

字符串
现在我想提取一个Map如下:
t1 -> T1; t2 -> T2; t3 -> T3
所以我可以确切地知道每个字段与哪个类型变量相关联。下面的代码不会作为通用擦除操作。

for (Field declaredField : RowClass.class.getDeclaredFields()) {
    System.out.println(declaredField.getName()+" -> " +declaredField.getType());
}
// t1 -> class java.lang.Object
// t2 -> class java.lang.Object
// t3 -> class java.lang.Object
// no type variable symbol printed


我为什么要问这个问题?只是为了学习,我试图了解Jackson如何将json字符串转换为声明泛型类型类,如List<String>
首先,我可以得到类型变量列表:

// the list of type variable
final TypeVariable<Class<RowClass>>[] typeParameters = RowClass.class.getTypeParameters();
Arrays.stream(typeParameters).forEach(System.out::println);


其次,我还可以得到实际参数的列表:

class RowClassImpl extends RowClass<String, Integer> {
}

final ParameterizedType parameterizedType = (ParameterizedType) (RowClassImpl.class.getGenericSuperclass());
Arrays.stream(parameterizedType.getActualTypeArguments()).forEach(type -> System.out.println(type.getTypeName()));


如果我能得到类型变量与字段的Map,我就可以保留每个字段的所有泛型信息。

bqucvtff

bqucvtff1#

  • "...现在我想提取一个Map如下:

t1 -> T1; t2 -> T2; t3 -> T3."*
顺便说一句,你写错了,应该是 T1 代替 t3
这里有一个例子。

RowClass<?, ?> r = new RowClass<>();
Map<String, Type> m
    = Stream.of(r.getClass().getDeclaredFields())
            .collect(Collectors.toMap(Field::getName, Field::getGenericType));

字符串
输出

{t1=T1, t2=T2, t3=T1}

os8fio9y

os8fio9y2#

前言:

你不能真正得到泛型变量的类型。

举例说明:

一个泛型getter必须返回一个String、String或其他值,这取决于T是什么。
你可以实现一个返回T的方法,但是你必须在那之后转换返回值,因为T不能做String可以做的事情。

保存T信息的方法:

你可以在一个String中保留T的类名-类似这样:
String classOfT = T.class

解决方案一:

你可以创建一个自定义的注解处理器,它在编译时自动创建类。就像Lombok为builder模式所做的那样。

解决方案二:

如果你像这样将它作为一个参数传递,你可以得到关于classOfT的信息:

public class TestMain {

    public static void main(String[] args) {
        new TestMain();
    }

    public TestMain() {
        MyList<String> myList = new MyList<>(String.class);
        System.out.println("classOfTAsString=" + myList.getClassOfTAsString());
    }

    public static class MyList<T> extends ArrayList<T> {

        private Class<T> classOfT;
        private String classOfTAsString;

        public MyList(Class<T> classOfT) {
            super();
            this.classOfT = classOfT;
            this.classOfTAsString = classOfT.getName(); // or getSimpleName();
        }

        public String getClassOfTAsString() {
            return classOfTAsString;
        }

    }

}

字符串

相关问题