转自:http://blog.csdn.net/ykdsg/archive/2010/04/11/5472591.aspx
很早之前写过利用泛型和反射机制抽象DAO ,对其中获取子类泛型的class一直不是很理解。关键的地方是HibernateBaseDao的构造方法中的
view plaincopy to clipboardprint?
Type genType = getClass().getGenericSuperclass();
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
entityClass = (Class)params[0];
但是这个相对子类才会有用,而且那篇文章的HibernateBaseDao还不是abstract,如果一不小心实例化的话就会报异常。感觉java中通过反射取泛型的class还是挺复杂的,不过一旦取到的话就可以做很多事情了。
改进的例子和测试:
1.先定义接口(这里写的比较简单就一个方法,具体可以再增加)
view plaincopy to clipboardprint?
public interface BaseDao<T> {
T get(String id);
}
2.定义抽象类实现接口
view plaincopy to clipboardprint?
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public abstract class HibernateBaseDao<T> implements BaseDao<T> {
private Class<T> entityClass;
/**
* 这个通常也是hibernate的取得子类class的方法
*
* @author "yangk"
* @date 2010-4-11 下午01:51:28
*/
public HibernateBaseDao() {
Type genType = getClass().getGenericSuperclass();
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
entityClass = (Class) params[0];
}
@Override
public T get(String id) {
try {
return entityClass.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
子类的构造函数会调用父类的构造函数,所以当子类实例化的时候,父类的entityClass 已经得到了T.class。
3.定义一个entity
view plaincopy to clipboardprint?
public class Entity {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4.定义entity的DAO
view plaincopy to clipboardprint?
public class EntityDao extends HibernateBaseDao<Entity> {
public void otherOperation() {
}
}
可以在里面定义父类没有的,针对具体子类特殊的方法。
5.测试
view plaincopy to clipboardprint?
import static org.junit.Assert.assertNotNull;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class JunitTest {
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
/**
* Test of getEClass method, of class tmp.
*/
@Test
public void testNewClass() {
EntityDao testDao = new EntityDao();
Entity e = testDao.get(null);
assertNotNull(e);
}
}
运行,可以看到测试顺利通过。
注意:上面子类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泛型的用法及T.class的获取过程解析 Java泛型是Java编程语言中的一种重要特性,它允许开发者在编写代码时指定类型参数,从而提高代码的灵活性和可读性。本文将详细介绍Java泛型的用法 及T.class的获取过程解析...
Java泛型是Java语言中用于处理类型安全的一种机制,它允许在编译期间提供类型检查,并在运行时消除了类型转换。Java泛型深入的内容涵盖泛型的基本概念、泛型类、接口、方法以及泛型的使用限制和高级特性。 首先,...
总结来说,`ReflectionUtil`工具类提供了一种方便的方式来处理Java泛型和反射操作,包括从`Type`获取`Class`对象,创建对象实例,以及获取泛型参数类型等。在实际开发中,正确、安全地使用反射对于提高代码的灵活性...
### Java泛型梳理 #### 一、泛型概念解析 泛型是一种参数化的类型机制,其核心在于将具体的类型参数化处理。这种处理方式类似于函数中的变量参数——具体类型可以在定义时留空,而在实际使用时传入。这种方式极大...
Java泛型是一种参数化的类型,它允许在声明类、接口和方法时使用类型参数。类型参数通常用大写字母表示,如`T`、`E`等,它们代表某种未知的类型。当创建泛型类的实例或调用泛型方法时,必须指定具体的类型,这称为...
### Java泛型详解 #### 一、什么是泛型? 在Java中引入泛型之前,开发者通常使用`Object`类型的集合来存储多种不同类型的对象。这种方式虽然灵活,但在使用过程中需要频繁进行类型检查或类型转换,这不仅增加了...
4. **利用`Class<T>`作为泛型约束**:有时候,我们可以在泛型类中使用`Class<T>`作为参数或字段,这样可以在运行时获取类型信息。例如: ```java public class MyClass<T> { private final Class<T> clazz; ...
Java泛型和Class类用法示例 Java泛型和Class类用法示例主要介绍了Java泛型和Class类用法,结合实例形式分析了java使用泛型限制class类避免强制类型转换相关操作技巧。本文将从以下几个方面详细讲解Java泛型和Class...
总的来说,理解和掌握Java泛型是提高代码质量、减少运行时错误的关键。通过泛型,我们可以编写更强大、更灵活、更安全的代码,同时避免不必要的类型转换。在实际开发中,泛型广泛应用于集合框架、工具类和设计模式中...
【Java泛型】Java泛型是自Java SE 1.5版本引入的一种强大的类型系统增强,旨在提升代码的安全性和重用性。它允许我们在编写代码时指定容器(如List、Set、Map等)能存储何种类型的元素,从而避免运行时的类型转换...
### Java使用泛型详解 #### 一、泛型的基本概念 在Java中,泛型是一种在编译时检查类型安全性的机制,它允许我们在类、接口或方法中使用类型参数来替代具体的类型。通过使用泛型,我们可以编写更加灵活、可重用性...
还有类型擦除,这是Java泛型的一个特性,意味着在运行时,所有的泛型信息都会被移除,因此泛型并不影响程序的性能,但它提供了编译时的类型检查。 在集合框架中,泛型发挥了重要作用。Java的List、Set、Map等集合类...
Java泛型是Java编程语言中的一个强大特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。这使得代码更加安全、可读性更强,并且能够减少类型转换的必要。在“java泛型的内部原理及更深应用”这个...
Java泛型是Java SE 5.0引入的一个重要特性,它极大地增强了代码的类型安全性和可读性。泛型在编程中的应用广泛,特别是在集合框架中,使得我们可以在编译时就检查类型,避免了不必要的类型转换,并且提高了代码的...
Java泛型是Java编程语言中的一个关键特性,它在2004年随着JDK 5.0的发布被引入,极大地增强了代码的类型安全性和重用性。本篇文章将带你入门Java泛型,通过实例深入理解其核心概念。 1. **泛型的基本概念** - 泛型...
Java泛型是Java编程语言中一个强大的特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。泛型的主要目标是提高代码的类型安全性和重用性,减少类型转换的麻烦,并在编译时捕获可能的类型错误。...
例如,`public class Box<T> { private T item; }`,这里的`T`就是一个类型参数,代表任意类型。 - **泛型接口**:接口也可以使用泛型,以便实现该接口的类必须遵循指定的类型规则。 - **泛型方法**:方法可以有...