-
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
相关推荐
2. **类型擦除**: 泛型在编译后会进行类型擦除,因此在运行时无法直接获取泛型类型信息。但泛型可以提供编译时的类型检查。 3. **通配符**: 通配符用于表示对类型的一般限制,如`?`表示任何类型,`? extends Number...
1. 反射(Reflection):Java反射机制允许程序在运行时动态地获取类的信息(如类名、方法名、参数类型等)并调用其方法。通过`Class`类,我们可以实例化未知类型的对象,调用私有方法,访问私有字段,以及检查类的...
提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class,java * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class,java * 反射工具类. 提供调用getter/...
- 反射API在泛型类型擦除后仍然能获取到泛型信息,这主要通过泛型类的类型参数的实际类型参数化实例(TypeToken)来实现。 - 这使得在运行时可以进行一些泛型相关的操作,如创建参数化的类实例。 总结来说,Java...
10. 泛型的局限性:由于类型擦除,泛型不能用于基本类型,所以Java提供了如`ArrayList<Integer>`这样的容器,实际上内部是通过包装类`Integer`实现的。另外,泛型也不能用于静态方法和变量,因为它们不属于任何特定...
Java泛型是Java编程语言中一个强大的特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。泛型的主要目标是提高代码的类型安全性和重用性,减少类型转换的麻烦,并在编译时捕获可能的类型错误。...
总结来说,Java反射提供了在运行时探索和操作类的能力,而泛型则增强了类型安全和代码复用。在`Testrefl.java`的例子中,这两者结合在一起,实现了动态创建和操作对象的能力,显示了Java编程的强大灵活性。理解并...
提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实...
泛型类型: 在 Java 5 之前,像 `Hashtable` 这样的集合类只能存储 `Object` 类型的数据,这意味着在使用集合时,程序员必须进行强制类型转换。这种转换可能导致 `ClassCastException`,增加了代码的脆弱性。泛型的...
尽管Java反射不直接支持泛型信息,但可以通过方法签名或字段类型来间接获取。例如,`List<?>`的`Class`类型是`java.util.List`,这意味着你不能直接获取泛型的实际类型参数。然而,你可以通过类型检查和转换来操作...
Java反射和泛型是两种强大的编程特性,它们在开发中有着广泛的应用,特别是在数据库操作的动态化场景下。本文将详细介绍如何结合这两种技术实现在Java中对MySQL、SQL Server或Oracle数据库进行动态的增删改查操作。 ...
这里的`<T>`就是泛型类型,`T`代表任何对象类型。通过这种方式,我们可以创建一个通用的DAO类,不指定具体的实体类,但在子类中指定时,编译器会进行类型检查,避免了类型转换的麻烦。 接着,我们讨论“反射”。...
通过反射获取的类信息中,泛型类型将表现为原始类型,但在编译时,泛型信息可用于类型检查。 9. **集合框架中的泛型**:Java集合框架广泛使用了泛型,如ArrayList、LinkedList、HashMap等。使用泛型,可以确保集合...
Java泛型是Java编程语言中的一种重要特性,它允许开发者在编写代码时指定类型参数,从而提高代码的灵活性和可读性。本文将详细介绍Java泛型的用法 及T.class的获取过程解析。 一、泛型的基本概念 泛型是Java 5中...
7. **泛型与反射**:讨论泛型如何与Java反射API交互,以及如何在反射中处理泛型类型。 8. **泛型与多态**:解释泛型如何影响类的继承和多态性,以及如何在泛型类的实例间进行方法重写。 9. **集合框架中的泛型**:...
泛型是Java SE 5版本引入的一个新特性,它的主要目的是允许在使用类、接口和方法时能够引用到任何类型的对象,同时在编译期间就能进行类型检查,提供更安全的代码。泛型类和泛型方法可以提高代码的复用性,并减少...
1. **Java反射**:反射API允许我们在运行时动态地获取类的信息(如类名、方法名、参数类型等)并调用这些方法。在处理数据库操作时,反射常用于动态地创建数据库连接、执行SQL语句,甚至根据数据库表结构自动生成...
Java 1.5 泛型是Java编程语言中的一项重要特性,它于2004年发布,极大地提升了代码的类型安全性和可读性。泛型允许开发者在类、接口和方法中使用类型参数,从而在编译时就能检查类型错误,避免了运行时的类型转换...
通过这个实战项目,你可以深入理解Java反射、泛型和注解的用法,并且了解到如何利用它们构建一个基本的依赖注入系统,这将有助于你更好地理解和使用Spring框架。同时,这样的实践也有助于提升你的编程技能,使你能够...
11. **泛型与反射**:在使用反射操作泛型类型时,需要注意类型信息在运行时是不可见的,需要通过其他方式(如注解或硬编码)来获取。 以上就是Java 5泛型新特性的一些关键点。通过这些特性,我们可以编写更安全、更...