-
Java 反射:怎么取出类的泛型类型5
public class BaseHello<T> { private Class<T> entityClass; public BaseHello(){ //entityClass怎么赋值?(怎么能知道entityClass就是代表Personal这个类?) } }
public static void main(String[] args) { BaseHello<Personal> pdao = new BaseHello<Personal>(); System.out.println(pdao); }
如注释的问题:在BaseHello的构造方法中,怎么给entityClass赋值?
问题补充:请注意这句 BaseHello<Personal> pdao = new BaseHello<Personal>(); 我是调用 BaseHello 这个类本身的构造方法,而不是一个他的子类的构造方法。
问题补充:其实我是想实现这样的:
public class BaseHello<T>{
public Class<T> entityClass;
public BaseHello(Class a) {
this.entityClass = a;
}
}
public static void main(String[] args) throws Exception{
BaseHello pdao = new BaseHello(Personal.class);
System.out.println(pdao);
}
这样功能倒是能实现,但是 这句这么写真的感觉好别扭
BaseHello pdao = new BaseHello(Personal.class);
我是想有反射应该不用这么写吧?
问题补充:结帖:问题出在
public class BaseHello<T> {
private Class<T> entityClass;
public BaseHello(){
}
}
这个类在运行期会出现泛型擦除的情况。
所以只能如 jinnianshilongnian 朋友所提的两种方法了。
感谢大家的热心帮助,结贴!
2012年9月22日 11:12
7个答案 按时间排序 按投票排序
-
采纳的答案
ParameterizedType parameterizedType = (ParameterizedType)this.getClass().getGenericSuperclass();
entityClass= (Class<T>)(parameterizedType.getActualTypeArguments()[0]);2012年9月22日 11:19
-
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; /** * 反射工具类 */ @SuppressWarnings("unchecked") public class ReflectUtils { /** * 获得超类的参数类型,取第一个参数类型 * @param <T> 类型参数 * @param clazz 超类类型 */ @SuppressWarnings("rawtypes") public static <T> Class<T> getClassGenricType(final Class clazz) { return getClassGenricType(clazz, 0); } /** * 根据索引获得超类的参数类型 * @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]; } }
public class PojoRawMapper<T> implements RowMapper<Object>{ protected Class<T> entityClass; public PojoRawMapper() { entityClass = ReflectUtils.getClassGenricType(getClass()); }
2012年9月23日 09:52
-
你调用的无参的构造函数:
BaseHello<Personal> pdao = new BaseHello<Personal>();
相当于变成了这样:public class BaseHello<Personal> { private Personal entityClass; public BaseHello(){ //entityClass怎么赋值?(怎么能知道entityClass就是代Personal这个类?) 你觉得这个地方你能怎么赋值?参数都不带!你想给entityClass赋值,就需要用带参数的构造函数。简单的事情不要整复杂了。 } public BaseHello(Class<T> arg){ 这个地方你晓得怎么赋值了吧? } }
2012年9月22日 17:00
-
因为类的成员变量在编译时会保留其类型信息的。
如下E是泛型类型,Set<E> e,在类型推导时会替换为Object的,所以你无法获取到类型信息,而e2,定义时就包含了类型信息,故可以获取到。public class TypesTest<E> { Set<E> e; Set<Integer> e2; }
完整测试代码如下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<String, Integer> a; Inner<Float, Double> b; List<Set<String>[][]> c; List<String> d; Set<String> e; Outer<String>.Inner f; private ParameterizedType mapStringInteger; private ParameterizedType innerFloatDouble; private ParameterizedType listSetStringArray; private ParameterizedType listString; private ParameterizedType setString; private ParameterizedType outerInner; private GenericArrayType setStringArray; private String toString(ParameterizedType parameterizedType) { Type[] types = parameterizedType.getActualTypeArguments(); String ret = "\n\t" + parameterizedType + "\n\t\t泛型个数:" + types.length + "==>"; for (Type type : types) { ret += type + ", "; } return ret; } @Test public void main() throws Exception { mapStringInteger = (ParameterizedType) getClass().getDeclaredField("a").getGenericType(); innerFloatDouble = (ParameterizedType) getClass().getDeclaredField("b").getGenericType(); listSetStringArray = (ParameterizedType) getClass().getDeclaredField("c").getGenericType(); listString = (ParameterizedType) getClass().getDeclaredField("d").getGenericType(); setString = (ParameterizedType) getClass().getDeclaredField("e").getGenericType(); outerInner = (ParameterizedType) getClass().getDeclaredField("f").getGenericType(); setStringArray = (GenericArrayType) listSetStringArray.getActualTypeArguments()[0]; System.out.println("a Map<String, Integer> 推导擦除后类型信息:" + toString(mapStringInteger)); System.out.println(); System.out.println("b Inner<Float, Double> 推导擦除后类型信息:" + toString(innerFloatDouble)); System.out.println(); System.out.println("c List<Set<String>[][]> 推导擦除后类型信息:" + toString(listSetStringArray)); System.out.println(); System.out.println("d List<String> 推导擦除后类型信息:" + toString(listString)); System.out.println(); System.out.println("e Set<String> 推导擦除后类型信息:" + toString(setString)); System.out.println(); System.out.println("f Outer<String>.Inner 推导擦除后类型信息:" + toString(outerInner)); System.out.println(); System.out.println("c List<Set<String>[][]> List第二层Set的泛型推导信息:" + setStringArray); } class Inner<T1, T2> { } static class Outer<T> { class Inner { } } }
2012年9月22日 15:04
-
不要再纠结这个问题了,这个没有解决方案,曾经和你一样的想法,记不清哪儿看的了,这个牵涉到泛型的擦除远离。
大意是:
1. 泛型编译时会推导擦除
2. 只有在编译时保存了类型信息时才能获得,运行时的泛型信息因为类型擦除所以肯定获取不到泛型的具体信息
详细测试见:public class TypesTest extends TestCase { Map<String, Integer> a; Inner<Float, Double> b; List<Set<String>[][]> c; List<String> d; Set<String> e; Outer<String>.Inner f; private ParameterizedType mapStringInteger; private ParameterizedType innerFloatDouble; private ParameterizedType listSetStringArray; private ParameterizedType listString; private ParameterizedType setString; private ParameterizedType outerInner; private GenericArrayType setStringArray; @Override protected void setUp() throws Exception { super.setUp(); mapStringInteger = (ParameterizedType) getClass().getDeclaredField("a") .getGenericType(); innerFloatDouble = (ParameterizedType) getClass().getDeclaredField("b") .getGenericType(); listSetStringArray = (ParameterizedType) getClass().getDeclaredField( "c").getGenericType(); listString = (ParameterizedType) getClass().getDeclaredField("d") .getGenericType(); setString = (ParameterizedType) getClass().getDeclaredField("e") .getGenericType(); outerInner = (ParameterizedType) getClass().getDeclaredField("f") .getGenericType(); setStringArray = (GenericArrayType) listSetStringArray .getActualTypeArguments()[0]; System.out.println(UtilJson.getObjectMapper() .writerWithType(TypesTest.class).writeValueAsString(this)); ; } class Inner<T1, T2> { } static class Outer<T> { class Inner { } } }
2012年9月22日 14:30
-
http://zx527291227.iteye.com/blog/1679332
可以看下这个,这是rapid-framework通用框架,里面有讲Base,
public class UserDao extends BaseHibernateDao<User, Long>{ @Override public Class getEntityClass() { return User.class; } }
你看下这样获取是否是你要的
2012年9月22日 14:15
-
Field[] fs = clazz.getDeclaredFields(); // 得到所有的fields for(Field f : fs) { Class fieldClazz = f.getType(); // 得到field的class及类型全路径 if(fieldClazz.isPrimitive()) continue; //【1】 //判断是否为基本类型 if(fieldClazz.getName().startsWith("java.lang")) continue; //getName()返回field的类型全路径; if(fieldClazz.isAssignableFrom(List.class)) //【2】 { Type fc = f.getGenericType(); // 关键的地方,如果是List类型,得到其Generic的类型 if(fc == null) continue; if(fc instanceof ParameterizedType) // 【3】如果是泛型参数的类型 { ParameterizedType pt = (ParameterizedType) fc; Class genericClazz = (Class)pt.getActualTypeArguments()[0]; //【4】 得到泛型里的class类型对象。 m.put(f.getName(), genericClazz); Map<String, Class> m1 = prepareMap(genericClazz); m.putAll(m1); } } }
2012年9月22日 11:25
相关推荐
而不是创建一个Object列表,你可以参数化java.util.List来创建一个String String列表,如下所示:当通过反射在运行时检查可参数化类型本
当我们声明了一个泛型的接口或类,或需要一个子类继承至这个泛型类,而我们又希望利用反射获取这些泛型参数信息。这是本文将要介绍的ReflectionUtil是为了解决这类问题的辅助工具类,为java.lang.reflect标准库的...
JAVA反射与动态代理 40 基本用法 40 处理泛型 42 动态代理 42 使用案例 43 参考资料 44 JAVA I/O 45 流 45 缓冲区 47 字符与编码 48 通道 49 参考资料 52 JAVA安全 53 认证 53 权限控制 55 加密、解密与签名 57 安全...
Java高级特性:反射、泛型、注释符、自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入。随书附赠光盘内容为《Java高手真经(编程基础卷):Java核心编程技术》各种原型包、系统源程序。
Java高级特性:反射、泛型、注释符、自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入。随书附赠光盘内容为《Java高手真经(编程基础卷):Java核心编程技术》各种原型包、系统源程序。
Java高级特性:反射、泛型、注释符、自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入。随书附赠光盘内容为《Java高手真经(编程基础卷):Java核心编程技术》各种原型包、系统源程序。
Java高级特性:反射、泛型、注释符、自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入。随书附赠光盘内容为《Java高手真经(编程基础卷):Java核心编程技术》各种原型包、系统源程序。
泛型是Java SE 1.5的新特性,好处是在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率。JAVA反射机制是构建框架技术的基础所在。灵活掌握Java反射机制,对以后学习框架有很大的帮助。...
Java高级特性:反射、泛型、注释符、自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入。随书附赠光盘内容为《Java高手真经(编程基础卷):Java核心编程技术》各种原型包、系统源程序。《Java高手...
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?...在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。
通过反射获得指定类的父类的泛型参数的实际类型
实现list不同泛型之间实体的互转,基于java8新特性+反射机制实现list不同实体类互转,将jdk8的流处理集合互转抽出来成一个工具类,实现lsit
Java基本数据类型 string和包装类 final关键字特性 Java类和包 抽象类和接口 代码块和代码执行顺序 Java自动拆箱装箱里隐藏的秘密 Java中的Class类和Object类 Java异常 解读Java中的回调 反射 泛型 枚举类 Java注解...
环境:Windows XP Professional、JDK 1.6、Ant 1.7 说明:Java泛型的动机是为解决类型转换在编译时不报错的问题。另外由于“范型编程”(Generic Programming)的推广,于是2004年JDK 5.0引用范型标准。本例子说明...
泛型 泛型类型的限定 3.反射 代码概述: bean :Person.java 这个人员类我就不说了 泛型dao接口 :GenericDao, ID extends Serializable> 泛型作为DAO的通用接口 CRUD方法 dao接口 : PersonDAO extends ...
面向对象:类、继承、多态、包、接口、抽象类、泛型等 异常处理:try-catch-finally、异常分类及处理、自定义异常等 线程:线程创建、线程同步、线程池等 反射机制:Class、Field、Method、Constructor等 注解:...
Java基本数据类型 字符串和包装类 关键字最终特性 Java类和包 抽象类和接口 代码块和代码执行顺序 Java自动拆箱装箱里隐藏的秘密 Java中的Class类和Object类 Java异常 解读Java中的回调 反射 泛型 枚举类 Java注解和...