如何在运行时(Runtime)获得泛型的真正类型

前言 由于Java 的类型擦除机制,在编译时泛型都被转为了Object,例如List经过编译之后将变为类型 List。可以通过以下的方式再运行时获得泛型的真正类型 泛型如何获得具体类型 List 例子如下 来自:https://stackoverflow.com/questions/1942644/get-generic-type-of-java-util-list package test; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.util.ArrayList; import java.util.List; public class Test { List stringList = new ArrayList(); List integerList = new ArrayList(); public static void main(String... args) throws Exception { Field stringListField = Test.class.getDeclaredField("stringList"); ParameterizedType stringListType = (ParameterizedType) stringListField.getGenericType(); Class stringListClass = (Class) stringListType.getActualTypeArguments()[0]; System.out.println(stringListClass); // class java.lang.String. Field integerListField = Test.class.getDeclaredField("integerList"); ParameterizedType integerListType = (ParameterizedType) integerListField.getGenericType(); Class integerListClass = (Class) integerListType.getActualTypeArguments()[0]; System.out.println(integerListClass); // class java.lang.Integer. } } Map 的例子如下 来自:https://stackoverflow.com/questions/3687766/how-to-get-value-type-of-a-map-in-java import java.lang.reflect.*; import java.util.*; public class Generic { private Map map = new HashMap(); public static void main(String[] args) { try { ParameterizedType pt = (ParameterizedType)Generic.class.getDeclaredField("map").getGenericType(); for(Type type : pt.getActualTypeArguments()) { System.out.println(type.toString()); } } catch(NoSuchFieldException e) { e.printStackTrace(); } } } 实际二者都利用的反射,都是基于 java.lang.reflect.ParameterizedType jackson 中如何反序列化泛型 jackson 中将JSON 转为Map 的可以通过如下代码实现,方式一: ObjectMapper mapper = new ObjectMapper(); String json = "{\"name\":\"mkyong\", \"age\":29}"; Map map = mapper.readValue(json, Map.class); Object name = map.get("name") 上述只是指定了是 Map 类型,但是没有指定Map里边存放的数据是什么类型,所以得到结果之后还需要对 Object name 做一次强制类型转换才能够使用。 可以使用方式二,告知实际 Map 中存放的对象,从而得到正确的类型,代码如下所示: ObjectMapper mapper = new ObjectMapper(); String json = "{\"name\":\"mkyong\", \"age\":29}"; Map map = mapper.readValue(json, new TypeReference>(){}); TypeReference实际上就是告诉了 ObjectMapper 反序列化时要转换的真正类型是什么。 TypeReference 源码 package com.fasterxml.jackson.core.type; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public abstract class TypeReference implements Comparable> { protected final Type _type; protected TypeReference() { Type superClass = this.getClass().getGenericSuperclass(); if (superClass instanceof Class) { throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information"); } else { this._type = ((ParameterizedType)superClass).getActualTypeArguments()[0]; } } public Type getType() { return this._type; } public int compareTo(TypeReference o) { return 0; } } 有一个 protected 的构造器,所以在使用的时候默认就会执行该构造器,上述方案二将会走到分支代码 this._type = ((ParameterizedType)superClass).getActualTypeArguments()[0];,从而 getType 能够得到正确的类型。实际上也是根据 ParameterizedType 获得真正的类型。 通过 TypeReference 获得真正类型 代码类似如下,最后得到的 tmpType1 是 Class 类型,就能够基于它其他的操作了。 TypeReference> typeReference = new TypeReference>(){}; ParameterizedType type = (ParameterizedType)typeReference.getType(); for (Type tmpType : type.getActualTypeArguments()) { Class tmpType1 = (Class) tmpType; System.out.println(tmpType1); } 欢迎转载,但请注明本文链接,谢谢你。https://www.cnblogs.com/xiaoheike/p/9867060.html
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信