泛型--Java 使⽤泛型编程提取类名上T 类型
抽象类的使用很早之前写过 ,对其中获取⼦类泛型的class ⼀直不是很理解。关键的地⽅是HibernateBaseDao 的构造⽅法中的
但是这个相对⼦类才会有⽤,⽽且那篇⽂章的HibernateBaseDao 还不是abstract ,如果⼀不⼩⼼实例化的话就会报异常。感觉java 中通过反射取泛型的class 还是挺复杂的,不过⼀旦取到的话就可以做很多事情了。
改进的例⼦和:
1.先定义接⼝(这⾥写的⽐较简单就⼀个⽅法,具体可以再增加)
2.定义抽象类实现接⼝
⼦类的构造函数会调⽤⽗类的构造函数,所以当⼦类实例化的时候,⽗类的entityClass 已经得到了T.class 。
3.定义⼀个entity
4.定义entity 的DAO []
01. Type genType = getClass().getGenericSuperclass(); 02. Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); 03. entityClass = (Class)params[0]; [java]
01. public interface BaseDao<T> { 02. T get(String id); 03. } [java]
01. import flect.ParameterizedType; 02. import flect.Type; 03. 04. public abstract class HibernateBaseDao<T> implements BaseDao<T> { 05. private Class<T> entityClass; 06. /** 07. * 这个通常也是的取得⼦类class 的⽅法08. */ 09. public HibernateBaseDao() { 10. Type genType = getClass().getGenericSuperclass(); 11. Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); 12. entityClass = (Class) params[0]; 13. }14. @Override 15. public T get(String id) { 16. try { 17. return wInstance(); 18. } catch (Exception e) {19. e.printStackTrace(); 20. } 21. return null ; 22. } 23. 24. }
[java]
01. public class Entity { 02. private String name; 03. public String getName() { 04. return name; 05. } 06. public void setName(String name) { 07. this .name = name; 08. } 09. }
可以在⾥⾯定义⽗类没有的,针对具体⼦类特殊的⽅法。
5.测试
运⾏,可以看到测试顺利通过。
注意:上⾯⼦类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 的⽅法。[c-sharp]
01. public class EntityDao extends HibernateBaseDao<Entity> {02. public void otherOperation() {03. }04. }[java]
01. import static org.junit.Assert.assertNotNull; 02. 03. import org.junit.After; 04. import org.junit.AfterClass; 05. import org.junit.Before; 06. import org.junit.BeforeClass; 07. import org.junit.Test; 08. 09. public class JunitTest { 10. @Test 11. public void testNewClass() { 12. EntityDao testDao = new EntityDao(); 13. Entity e = (null ); 14. assertNotNull(e); 15. }16.
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论