`

java泛型T.class的获取(转)

阅读更多
转自: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泛型的用法及T.class的获取过程解析 Java泛型是Java编程语言中的一种重要特性,它允许开发者在编写代码时指定类型参数,从而提高代码的灵活性和可读性。本文将详细介绍Java泛型的用法 及T.class的获取过程解析...

    java泛型深入.pdf

    Java泛型是Java语言中用于处理类型安全的一种机制,它允许在编译期间提供类型检查,并在运行时消除了类型转换。Java泛型深入的内容涵盖泛型的基本概念、泛型类、接口、方法以及泛型的使用限制和高级特性。 首先,...

    反射处理java泛型_.docx

    总结来说,`ReflectionUtil`工具类提供了一种方便的方式来处理Java泛型和反射操作,包括从`Type`获取`Class`对象,创建对象实例,以及获取泛型参数类型等。在实际开发中,正确、安全地使用反射对于提高代码的灵活性...

    Java泛型梳理.

    ### Java泛型梳理 #### 一、泛型概念解析 泛型是一种参数化的类型机制,其核心在于将具体的类型参数化处理。这种处理方式类似于函数中的变量参数——具体类型可以在定义时留空,而在实际使用时传入。这种方式极大...

    关于java的泛型.doc

    Java泛型是一种参数化的类型,它允许在声明类、接口和方法时使用类型参数。类型参数通常用大写字母表示,如`T`、`E`等,它们代表某种未知的类型。当创建泛型类的实例或调用泛型方法时,必须指定具体的类型,这称为...

    Java-泛型.ppt

    ### Java泛型详解 #### 一、什么是泛型? 在Java中引入泛型之前,开发者通常使用`Object`类型的集合来存储多种不同类型的对象。这种方式虽然灵活,但在使用过程中需要频繁进行类型检查或类型转换,这不仅增加了...

    java 泛型类的类型识别示例

    4. **利用`Class&lt;T&gt;`作为泛型约束**:有时候,我们可以在泛型类中使用`Class&lt;T&gt;`作为参数或字段,这样可以在运行时获取类型信息。例如: ```java public class MyClass&lt;T&gt; { private final Class&lt;T&gt; clazz; ...

    Java泛型和Class类用法示例

    Java泛型和Class类用法示例 Java泛型和Class类用法示例主要介绍了Java泛型和Class类用法,结合实例形式分析了java使用泛型限制class类避免强制类型转换相关操作技巧。本文将从以下几个方面详细讲解Java泛型和Class...

    java接口泛型.pdf

    总的来说,理解和掌握Java泛型是提高代码质量、减少运行时错误的关键。通过泛型,我们可以编写更强大、更灵活、更安全的代码,同时避免不必要的类型转换。在实际开发中,泛型广泛应用于集合框架、工具类和设计模式中...

    浅析Java泛型的使用.pdf

    【Java泛型】Java泛型是自Java SE 1.5版本引入的一种强大的类型系统增强,旨在提升代码的安全性和重用性。它允许我们在编写代码时指定容器(如List、Set、Map等)能存储何种类型的元素,从而避免运行时的类型转换...

    java 使用泛型.txt

    ### Java使用泛型详解 #### 一、泛型的基本概念 在Java中,泛型是一种在编译时检查类型安全性的机制,它允许我们在类、接口或方法中使用类型参数来替代具体的类型。通过使用泛型,我们可以编写更加灵活、可重用性...

    JAVA泛型详解[参考].pdf

    还有类型擦除,这是Java泛型的一个特性,意味着在运行时,所有的泛型信息都会被移除,因此泛型并不影响程序的性能,但它提供了编译时的类型检查。 在集合框架中,泛型发挥了重要作用。Java的List、Set、Map等集合类...

    java泛型的内部原理及更深应用

    Java泛型是Java编程语言中的一个强大特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。这使得代码更加安全、可读性更强,并且能够减少类型转换的必要。在“java泛型的内部原理及更深应用”这个...

    关于java基础的泛型的练习

    Java泛型是Java SE 5.0引入的一个重要特性,它极大地增强了代码的类型安全性和可读性。泛型在编程中的应用广泛,特别是在集合框架中,使得我们可以在编译时就检查类型,避免了不必要的类型转换,并且提高了代码的...

    java 泛型入门 实例

    Java泛型是Java编程语言中的一个关键特性,它在2004年随着JDK 5.0的发布被引入,极大地增强了代码的类型安全性和重用性。本篇文章将带你入门Java泛型,通过实例深入理解其核心概念。 1. **泛型的基本概念** - 泛型...

    Java泛型_Java中的泛型结构_

    Java泛型是Java编程语言中一个强大的特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。泛型的主要目标是提高代码的类型安全性和重用性,减少类型转换的麻烦,并在编译时捕获可能的类型错误。...

    05-java泛型的使用.doc

    例如,`public class Box&lt;T&gt; { private T item; }`,这里的`T`就是一个类型参数,代表任意类型。 - **泛型接口**:接口也可以使用泛型,以便实现该接口的类必须遵循指定的类型规则。 - **泛型方法**:方法可以有...

Global site tag (gtag.js) - Google Analytics