java中泛型T class的获取? 400 报错
我定义了一个泛型父类,用resovleClazzInfo方法获取实体的真是类型:
public abstract class AbstractDBDao<T extends DBModel> implements BaseDao<T> { private Class<T> entityClazz; public AbstractDBDao(Context context) { resovleClazzInfo(); } private void resovleClazzInfo() { Type genType = getClass().getGenericSuperclass(); Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); entityClazz = (Class) params[0]; } }
static class NirvanaDao<T> extends AbstractDao<T> { } public static <T> BaseDao<T> getDao(Class<T> clazz) { BaseDao<T> dao = new NirvanaDao<T>(); return dao; } public static main(String[] args) { getDao(StudentModel.class); }
错误如下:
Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType at com.xckevin.test.AbstractDao.<init>(AbstractDao.java:11) at com.xckevin.test.NirvanaDao.<init>(NirvanaDao.java:4) at com.xckevin.test.Test.main(Test.java:8)
求问为什么,原理是什么?如何解决这个问题。
你这个一看就是静态内部类,不行的啦。
你可以稍微搭一眼看看,你就会发现,你的StudentModel.class根本就没有传递到getDao方法里面的NirvanaDao的<T>上面去的哈。如果没传递过去值,那么在父类上调用getGenericSuperclass时,就因为当前类<T>没有具体值,就是,T代表的不是一个具体的类,而就是字母T,那就会报错咯吖。
######回复 @iuKa : 好的,谢谢你的帮助######回复 @iuKa : 不能,<T>中只能直接写类名字,这个类名字,在java中不是通过class能得到的,而且2个是不等同的概念。所以,不行。######是的,调试的时候发现确实是字母T。那么该怎么传递什么样的参数才能将T替换成StudentModel呢?######虽然我不会,但还是推荐把报的错贴出来吧######把Class<T> entityClazz;改成Class entityClazz;试试,粗看起来像在后面(class)params[0]赋值时无法转换类型。######谢谢提醒,已贴。######因为编译时的类型擦除机制,这样是取不到的,这个问题我在写框架时候就发现了
具体你可以参考HibernateDaoSupport的实现和使用,也是泛型类,实际在用的时候,继承时<T>必须指定
正如楼上所说,你只能取到T,不能取到具体的类,断点看看就知道了
######多谢提醒,立马去看。 那么就不能通过这种方法去生成dao了吗?这样每个Model需要实现一个实现一个dao,是不是太麻烦了。 另外想了一个办法就是动态生成class,然后加载使用。版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。