Java 反射:怎么取出类的泛型类型

[code="java"]
public class BaseHello {
private Class entityClass;

 public BaseHello(){
     //entityClass怎么赋值?(怎么能知道entityClass就是代表Personal这个类?)
 }

}
[/code]
[code="java"]
public static void main(String[] args) {
BaseHello pdao = new BaseHello();
System.out.println(pdao);
}
[/code]
如注释的问题:在BaseHello的构造方法中,怎么给entityClass赋值?


慕妹3242003
浏览 1464回答 7
7回答

森栏

ParameterizedType parameterizedType = (ParameterizedType)this.getClass().getGenericSuperclass();entityClass= (Class)(parameterizedType.getActualTypeArguments()[0]);

BIG阳

可以看下这个,这是rapid-framework通用框架,里面有讲Base,[code="java"]public class UserDao extends BaseHibernateDao{@Override   public Class getEntityClass() {       return User.class;   }}[/code]你看下这样获取是否是你要的

烙印99

不要再纠结这个问题了,这个没有解决方案,曾经和你一样的想法,记不清哪儿看的了,这个牵涉到泛型的擦除远离。大意是:1. 泛型编译时会推导擦除2. 只有在编译时保存了类型信息时才能获得,运行时的泛型信息因为类型擦除所以肯定获取不到泛型的具体信息详细测试见:[code="java"]public class TypesTest extends TestCase {Map a;Inner b;List[][]> c;List d;Set e;Outer.Inner f;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ParameterizedType&nbsp;mapStringInteger; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ParameterizedType&nbsp;innerFloatDouble; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ParameterizedType&nbsp;listSetStringArray; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ParameterizedType&nbsp;listString; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ParameterizedType&nbsp;setString; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ParameterizedType&nbsp;outerInner; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;GenericArrayType&nbsp;setStringArray; &nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;setUp()&nbsp;throws&nbsp;Exception&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super.setUp(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mapStringInteger&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField("a") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;innerFloatDouble&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField("b") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listSetStringArray&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"c").getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listString&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField("d") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setString&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField("e") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outerInner&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField("f") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setStringArray&nbsp;=&nbsp;(GenericArrayType)&nbsp;listSetStringArray &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getActualTypeArguments()[0]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(UtilJson.getObjectMapper() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.writerWithType(TypesTest.class).writeValueAsString(this)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Inner<T1,&nbsp;T2>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;class&nbsp;Outer<T>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Inner&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}}[/code]

动漫人物

因为类的成员变量在编译时会保留其类型信息的。如下E是泛型类型,Set e,在类型推导时会替换为Object的,所以你无法获取到类型信息,而e2,定义时就包含了类型信息,故可以获取到。[code="java"]public class TypesTest {Set e;Set e2;}[/code]完整测试代码如下[code="java"]import java.lang.reflect.GenericArrayType;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.util.List;import java.util.Map;import java.util.Set;import org.junit.Test;public class TypesTest {Map a;Inner b;List[][]> c;List d;Set e;Outer.Inner f;private&nbsp;ParameterizedType&nbsp;mapStringInteger; private&nbsp;ParameterizedType&nbsp;innerFloatDouble; private&nbsp;ParameterizedType&nbsp;listSetStringArray; private&nbsp;ParameterizedType&nbsp;listString; private&nbsp;ParameterizedType&nbsp;setString; private&nbsp;ParameterizedType&nbsp;outerInner; private&nbsp;GenericArrayType&nbsp;setStringArray; private&nbsp;String&nbsp;toString(ParameterizedType&nbsp;parameterizedType)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;Type[]&nbsp;types&nbsp;=&nbsp;parameterizedType.getActualTypeArguments(); &nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ret&nbsp;=&nbsp;"\n\t"&nbsp;+&nbsp;parameterizedType&nbsp;+&nbsp;"\n\t\t泛型个数:"&nbsp;+&nbsp;types.length&nbsp;+&nbsp;"==>"; &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(Type&nbsp;type&nbsp;:&nbsp;types)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;+=&nbsp;type&nbsp;+&nbsp;",&nbsp;"; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ret; } @Test public&nbsp;void&nbsp;main()&nbsp;throws&nbsp;Exception&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;mapStringInteger&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField("a").getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;innerFloatDouble&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField("b").getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;listSetStringArray&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField("c").getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;listString&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField("d").getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;setString&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField("e").getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;outerInner&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getDeclaredField("f").getGenericType(); &nbsp;&nbsp;&nbsp;&nbsp;setStringArray&nbsp;=&nbsp;(GenericArrayType)&nbsp;listSetStringArray.getActualTypeArguments()[0]; &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("a&nbsp;Map<String,&nbsp;Integer>&nbsp;推导擦除后类型信息:"&nbsp;+&nbsp;toString(mapStringInteger)); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println(); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("b&nbsp;Inner<Float,&nbsp;Double>&nbsp;推导擦除后类型信息:"&nbsp;+&nbsp;toString(innerFloatDouble)); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println(); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("c&nbsp;List<Set<String>[][]>&nbsp;推导擦除后类型信息:"&nbsp;+&nbsp;toString(listSetStringArray)); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println(); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("d&nbsp;List<String>&nbsp;推导擦除后类型信息:"&nbsp;+&nbsp;toString(listString)); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println(); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("e&nbsp;Set<String>&nbsp;推导擦除后类型信息:"&nbsp;+&nbsp;toString(setString)); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println(); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("f&nbsp;Outer<String>.Inner&nbsp;推导擦除后类型信息:"&nbsp;+&nbsp;toString(outerInner)); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println(); &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("c&nbsp;List<Set<String>[][]>&nbsp;List第二层Set的泛型推导信息:"&nbsp;+&nbsp;setStringArray); } class&nbsp;Inner<T1,&nbsp;T2>&nbsp;{ } static&nbsp;class&nbsp;Outer<T>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Inner&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} }}

桃花长相依

你调用的无参的构造函数:BaseHello pdao = new BaseHello();相当于变成了这样:[code="java"]public class BaseHello {private Personal entityClass;&nbsp;public&nbsp;BaseHello(){&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//entityClass怎么赋值?(怎么能知道entityClass就是代Personal这个类?)&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;你觉得这个地方你能怎么赋值?参数都不带!你想给entityClass赋值,就需要用带参数的构造函数。简单的事情不要整复杂了。 &nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;public&nbsp;BaseHello(Class<T>&nbsp;arg){&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;这个地方你晓得怎么赋值了吧?}}

眼眸繁星

import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;/**反射工具类*/@SuppressWarnings("unchecked")public class ReflectUtils {/**/**public PojoRawMapper() {entityClass = ReflectUtils.getClassGenricType(getClass());}根据索引获得超类的参数类型@param clazz 超类类型@param index 索引 */ @SuppressWarnings("rawtypes") public static Class getClassGenricType(final Class clazz, final int index) { Type genType = clazz.getGenericSuperclass(); if (!(genType instanceof ParameterizedType)) { return Object.class; } Type[] params = ((ParameterizedType)genType).getActualTypeArguments(); if (index >= params.length || index < 0) { return Object.class; } if (!(params[index] instanceof Class)) { return Object.class; } return (Class) params[index]; } } [/code] [code="java"] public class PojoRawMapper implements RowMapper{ protected Class entityClass;获得超类的参数类型,取第一个参数类型@param 类型参数@param clazz 超类类型 */ @SuppressWarnings("rawtypes") public static Class getClassGenricType(final Class clazz) { return getClassGenricType(clazz, 0); }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java