很早之前写过利用泛型和反射机制抽象DAO ,对其中获取子类泛型的class一直不是很理解。关键的地方是HibernateBaseDao的构造方法中的

  1. Type genType = getClass().getGenericSuperclass();
  2. Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
  3. entityClass =  (Class)params[0];

但是这个相对子类才会有用,而且那篇文章的HibernateBaseDao还不是abstract,如果一不小心实例化的话就会报异常。感觉java中通过反射取泛型的class还是挺复杂的,不过一旦取到的话就可以做很多事情了。

改进的例子和测试:

1.先定义接口(这里写的比较简单就一个方法,具体可以再增加)

  1. public interface BaseDao<T> {
  2. T get(String id);
  3. }

2.定义抽象类实现接口

  1. import java.lang.reflect.ParameterizedType;
  2. import java.lang.reflect.Type;
  3. public abstract class HibernateBaseDao<T> implements BaseDao<T> {
  4. private Class<T> entityClass;
  5. /**
  6. * 这个通常也是hibernate的取得子类class的方法
  7. *
  8. * @author "yangk"
  9. * @date 2010-4-11 下午01:51:28
  10. */
  11. public HibernateBaseDao() {
  12. Type genType = getClass().getGenericSuperclass();
  13. Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
  14. entityClass = (Class) params[0];
  15. }
  16. @Override
  17. public T get(String id) {
  18. try {
  19. return entityClass.newInstance();
  20. } catch (InstantiationException e) {
  21. // TODO Auto-generated catch block
  22. e.printStackTrace();
  23. } catch (IllegalAccessException e) {
  24. // TODO Auto-generated catch block
  25. e.printStackTrace();
  26. }
  27. return null;
  28. }
  29. }

子类的构造函数会调用父类的构造函数,所以当子类实例化的时候,父类的entityClass 已经得到了T.class。

3.定义一个entity

  1. public class Entity {
  2. private String name;
  3. public String getName() {
  4. return name;
  5. }
  6. public void setName(String name) {
  7. this.name = name;
  8. }
  9. }

4.定义entity的DAO

  1. public class EntityDao extends HibernateBaseDao<Entity> {
  2. public void otherOperation() {
  3. }
  4. }

可以在里面定义父类没有的,针对具体子类特殊的方法。

5.测试

  1. import static org.junit.Assert.assertNotNull;
  2. import org.junit.After;
  3. import org.junit.AfterClass;
  4. import org.junit.Before;
  5. import org.junit.BeforeClass;
  6. import org.junit.Test;
  7. public class JunitTest {
  8. @BeforeClass
  9. public static void setUpClass() throws Exception {
  10. }
  11. @AfterClass
  12. public static void tearDownClass() throws Exception {
  13. }
  14. @Before
  15. public void setUp() {
  16. }
  17. @After
  18. public void tearDown() {
  19. }
  20. /**
  21. * Test of getEClass method, of class tmp.
  22. */
  23. @Test
  24. public void testNewClass() {
  25. EntityDao testDao = new EntityDao();
  26. Entity e = testDao.get(null);
  27. assertNotNull(e);
  28. }
  29. }

运行,可以看到测试顺利通过。

注意:上面子类DAO的写法public class EntityDao extends HibernateBaseDao<Entity>

一定要在父类后面带上泛型,负责编译就会出错。

附:这是泛型擦拭法使得Generic无法获取自己的Generic Type类型。实际上BadClass<String>()实例化以后Class里面就不包括T的信息了,对于Class而言T已经被擦拭为Object,而真正的T参数被转到使用T的方法(或者变量声明或者其它使用T的地方)里面(如果没有那就没有存根),所以无法反射到T的具体类别,也就无法得到T.class。而getGenericSuperclass()是Generic继承的特例,对于这种情况子类会保存父类的Generic参数类型,返回一个ParameterizedType,这时可以获取到父类的T.class了,这也正是子类确定应该继承什么T的方法。

java 反射 子类泛型的class的更多相关文章

  1. Java反射给泛型集合赋值

    Java反射给泛型集合赋值 泛型 Java泛型简单描述下: 比如创建一个List集合,我想在里边只放Student对象信息,就需要写成 List<Student> studentList ...

  2. 深入分析Java反射(三)-泛型

    前提 Java反射的API在JavaSE1.7的时候已经基本完善,但是本文编写的时候使用的是Oracle JDK11,因为JDK11对于sun包下的源码也上传了,可以直接通过IDE查看对应的源码和进行 ...

  3. Java反射,泛型在Json中的运用

    最近项目中遇到了Json数据自动获取的功能,不然令人想起java的反射,已经很长时间没复习java了正好一块连java的这一块内容一起过一遍.java中的反射无疑就相当于java开发者的春天,在众多的 ...

  4. 2015第22周六Java反射、泛型、容器简介

    Java的反射非常强大,传递class, 可以动态的生成该类.取得这个类的所有信息,包括里面的属性.方法以及构造函数等,甚至可以取得其父类或父接口里面的内容. obj.getClass().getDe ...

  5. java 反射和泛型

    反射 在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问.检测和修改它本身状态或行为的一种能力.[1]用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为. 要注意术 ...

  6. java 反射和泛型-反射来获取泛型信息

    通过指定对应的Class对象,程序可以获得该类里面所有的Field,不管该Field使用private 方法public.获得Field对象后都可以使用getType()来获取其类型. Class&l ...

  7. 关于java反射获取泛型

    public class Test<T> { private final TypeToken<T> typeToken = new TypeToken<T>(get ...

  8. java反射获得泛型参数getGenericSuperclass():获取到父类泛型的类型

    public class Person<T> { } import java.lang.reflect.ParameterizedType; import java.lang.reflec ...

  9. Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题

    在开发时,遇到了下面这条语句,不懂,然习之. private List<MyZhuiHaoDetailModel> listLottery = new ArrayList<MyZhu ...

随机推荐

  1. MemAdmin 轻量级可视化Memcached管理工具

    蛮好用的 具体功能看图 开源地址:https://github.com/junstor/memadmin

  2. LVM : 扩展文件系统的容量

    如果发现文件系统的容量不足了,可以通过 LVM 轻松的进行扩展(当然也可以进行缩减操作).本文将紧接前文中的 demo 详细的介绍扩展文件系统的操作过程.说明:本文的演示环境为 ubuntu 16.0 ...

  3. 计算机网络什么是OSI7层模型、TCP/IP4层模型理解

    模型图解 应用层 就是最顶层的.通常指的应用程序初始走的协议比如有 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 表示层 主要对数据应用层的数据包进行加密 会话层 建立.管理. ...

  4. PAT甲级题解-1066. Root of AVL Tree (25)-AVL树模板题

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6803291.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  5. Genymotion安装总结

    周末的时候为了测试论文中的Almond虚拟助手软件,所以要去Google Play上去下载. 但是我的两个安卓模拟器:夜神和海马玩模拟器的安卓版本太低了,导致无法使用 谷歌服务,所以连商店都进不去. ...

  6. 搭建ssm的步骤

    搭建SSM的步骤 ----------------------------- 1.创建web工程 2.把SSM做需要的所有jar导入工程中 3.web.xml 1.Springmvc的前端控制器,如果 ...

  7. 关于<T> T[] toArray(T[] a) 方法

    http://mopishv0.blog.163.com/blog/static/5445593220101016102129741/ private List<String> uploa ...

  8. WIN10护眼色

    参看文章:http://www.xitongcheng.com/jiaocheng/win10_article_10326.html WIN10:[HKEY_CURRENT_USER\Control ...

  9. laravel orm 中的一对多关系 hasMany

    个人对于laravel orm 中对于一对多关系的理解 文章表 article,文章自然可以评论,表 comment 记录文章的评论,文章和评论的关系就是一对多,一篇文章可以有多个评论. 在 comm ...

  10. [CNBETA]Intel CPU底层漏洞事件完全详解:全球手机/电脑无一幸免[转帖]

    http://www.cnbeta.com/articles/tech/685897.htm 由Intel CPU漏洞问题衍生出来的安全事件已经波及全球几乎所有的手机.电脑.云计算产品,ARM确认 C ...