`

java 通过反射获取泛型的类型

 
阅读更多

jdk1.5开始支持泛型,所以我们有时需要把泛型里定义的对象的类型拿到

比如现在我定义了三个类Account, AccountItem和Product类。

Account聚合AccountItem,AccountItem聚合Prodcut。

都是用List<AccountItem>和List<Product>来表示的

我要实现一个功能,需要动态的传入一个Class的类型,然后反射到启动的List,根据List里定义的泛型,知道其中List的具体对象。

这个需求主要是由于现在的Json-lib还不支持深度的List的unmarshall,而只支持数组的方式。其实这里就是json-lib的beanfactory用到ezmorpher,而ezmorpher不支持泛型的定义方式,所以不知道类型,全转成MorpherDynBean,这样的对象是我们不需要的。

这样需要修改ezmorpher的代码,注入自己的MorpherBean的processor,这个processor就根据泛型拿到,我们需要转型的对象。

代码片段如下

Field[] fs = clazz.getDeclaredFields(); // 得到所有的fields

for(Field f : fs) 
{ 
    Class fieldClazz = f.getType(); // 得到field的class及类型全路径

    if(fieldClazz.isPrimitive())  continue;  //【1】 //判断是否为基本类型

    if(fieldClazz.getName().startsWith("java.lang")) continue; //getName()返回field的类型全路径;

    if(fieldClazz.isAssignableFrom(List.class)) //【2】
    { 
             Type fc = f.getGenericType(); // 关键的地方,如果是List类型,得到其Generic的类型

             if(fc == null) continue;

             if(fc instanceof ParameterizedType) // 【3】如果是泛型参数的类型 
            { 
                   ParameterizedType pt = (ParameterizedType) fc;

                   Class genericClazz = (Class)pt.getActualTypeArguments()[0]; //【4】 得到泛型里的class类型对象。

                   m.put(f.getName(), genericClazz);

                   Map<String, Class> m1 = prepareMap(genericClazz);

                   m.putAll(m1); 
             } 
      } 
}

 

 

【解释】:
1、isPrimitive

public boolean isPrimitive()判定指定的 Class 对象是否表示一个基本类型。
有九种预定义的 Class 对象,表示八个基本类型和 void。这些类对象由 Java 虚拟机创建,与其表示的基本类型同名,即 boolean、byte、char、short、int、long、float 和 double。 【注:像Integer,Boolean等包装类不是基本类型!】

这些对象仅能通过下列声明为 public static final 的变量访问,也是使此方法返回 true 的仅有的几个 Class 对象。 

返回: 当且仅当该类表示一个基本类型时,才返回 true
从以下版本开始:JDK1.1

2、isAssignableFrom
Java代码 复制代码 收藏代码
  1. System.out.println(String.class.isAssignableFrom(Object.class));     
System.out.println(String.class.isAssignableFrom(Object.class));   

2.//打印true  
    AA.class.isAssignableFrom(BB.class)的作用是判定AA表示的类或接口是否同参数BB指定的类表示的类或接口相同,或AA是否是BB的父类。

Java代码 复制代码 收藏代码
  1. System.out.println( String.class.isAssignableFrom(Object.class) ) ;       false  
  2. System.out.println( Object.class.isAssignableFrom(Object.class) );       true  
  3. System.out.println( Object.class.isAssignableFrom(String.class) );        true  
  4. String ss = "";      
  5. System.out.println( ss instanceof Object );         true  
  6. Object o = new   Object();   
  7. System.out.println( o instanceof Object );           true  

3、ParameterizedType 表示参数化类型,如 Collection<String>。

4、getGenericSuperclass, getSuperclass, getActualTypeArguments

     说明

           1.Class<? super T> getSuperclass():返回本类的父类

           2.Type getGenericSuperclass():返回本类的父类,包含泛型参数信息

      例子
          1.ClassA.java

Java代码 复制代码 收藏代码
  1.   public class  ClassA <T>{        
  2.       private T obj;        
  3.       public void setObject(T obj) {      this.obj = obj;  }      
  4.       public T getObject() {    return obj;   }        
  5. }    
           public class  ClassA <T>{     
                 private T obj;     
                 public void setObject(T obj) {      this.obj = obj;  }   
                 public T getObject() {    return obj;   }     
           }  



         2.Test.java

Java代码 复制代码 收藏代码
  1.     
  2. import java.lang.reflect.Type;       
  3. import java.lang.reflect.ParameterizedType;      
  4. public class Test<T> extends ClassA<T>{      
  5.     private List<String> list;      
  6.   
  7.     public void testA(){   
  8.         Type t = Test.class.getDeclaredField("list").getGenericType();   
  9.         if (ParameterizedType.class.isAssignableFrom(t.getClass())) {               
  10.             for (Type t1:((ParameterizedType)t).getActualTypeArguments()) {           
  11.                 System.out.print(t1 + ",");           
  12.             }           
  13.             System.out.println();           
  14.         }    
  15.    }   
  16.    public static void main(String args[]) throws Exception{        
  17.             System.out.println("======getSuperclass======:");       
  18.             System.out.println(Test.class.getSuperclass().getName());      
  19.             System.out.println("======getGenericSuperclass======:");      
  20.             Type t = Test.class.getGenericSuperclass();       
  21.             System.out.println(t);        
  22.             if (ParameterizedType.class.isAssignableFrom(t.getClass())) {     
  23.                      System.out.print("----------->getActualTypeArguments:");        
  24.                      for (Type t1:((ParameterizedType)t).getActualTypeArguments()) {        
  25.                                     System.out.print(t1 + ",");        
  26.                       }        
  27.                      System.out.println();        
  28.             }     
  29.    }      
  30.   
  31.   }    
 
import java.lang.reflect.Type;    
import java.lang.reflect.ParameterizedType;   
public class Test<T> extends ClassA<T>{   
	private List<String> list;   

    public void testA(){
    	Type t = Test.class.getDeclaredField("list").getGenericType();
    	if (ParameterizedType.class.isAssignableFrom(t.getClass())) {            
    		for (Type t1:((ParameterizedType)t).getActualTypeArguments()) {        
    			System.out.print(t1 + ",");        
    		}        
    		System.out.println();        
    	} 
   }
   public static void main(String args[]) throws Exception{     
            System.out.println("======getSuperclass======:");    
            System.out.println(Test.class.getSuperclass().getName());   
            System.out.println("======getGenericSuperclass======:");   
            Type t = Test.class.getGenericSuperclass();    
            System.out.println(t);     
            if (ParameterizedType.class.isAssignableFrom(t.getClass())) {  
                     System.out.print("----------->getActualTypeArguments:");     
                     for (Type t1:((ParameterizedType)t).getActualTypeArguments()) {     
                                    System.out.print(t1 + ",");     
                      }     
                     System.out.println();     
            }  
   }   

  }  

              输出结果:
class java.lang.String,
                    ======getSuperclass======:
                    ClassA
                    ======getGenericSuperclass======:
                    ClassA<T>
                    ----------->getActualTypeArguments:T,

分享到:
评论

相关推荐

    java反射与泛型综合例子

    总结来说,Java反射提供了在运行时探索和操作类的能力,而泛型则增强了类型安全和代码复用。在`Testrefl.java`的例子中,这两者结合在一起,实现了动态创建和操作对象的能力,显示了Java编程的强大灵活性。理解并...

    Java试题-3:反射和泛型的综合应用

    Java试题-3:反射和泛型的综合应用 Java反射 泛型都是比较高级的应用技术

    Java泛型的用法及T.class的获取过程解析

    2. 泛型 + 反射:泛型可以与反射结合使用,通过反射的API来获取T的Class。 3. 收敛:泛型可以增加类型安全,减少了强制类型转换的代码。 4. MetaProgramming:泛型可以在编译期搞很多东西,比如MetaProgramming。 ...

    java 基于泛型与反射的通用 DAO

    这里的`&lt;T&gt;`就是泛型类型,`T`代表任何对象类型。通过这种方式,我们可以创建一个通用的DAO类,不指定具体的实体类,但在子类中指定时,编译器会进行类型检查,避免了类型转换的麻烦。 接着,我们讨论“反射”。...

    654.652.JAVA基础教程_反射-获取运行时类的父类及父类的泛型(654).rar

    然而,由于类型擦除,运行时无法直接获取泛型类型参数。但是,我们可以通过检查方法或字段的签名来间接获取这些信息。 例如,假设我们有一个如下父类: ```java public class ParentClass&lt;T&gt; { private List&lt;T&gt; ...

    Java 获取泛型的类型实例详解

    使用反射机制获取泛型的类型实例是指使用 Java 的反射机制来获取泛型的类型实例,例如,我们可以使用 `getDeclaredField` 方法来获取类的字段,然后使用 `getGenericType` 方法来获取泛型类型实例。 ```java public...

    Java反射泛型,实现数据库的动态增删改查等功能

    具体实现时,我们可以为每个数据库操作创建一个泛型方法,使用反射获取实体类的字段,根据字段生成对应的SQL语句片段。比如在插入操作中,我们可以遍历`T`的所有字段,构建一个`INSERT INTO table_name (field1, ...

    JAVA5泛型和反射

    泛型类型: 在 Java 5 之前,像 `Hashtable` 这样的集合类只能存储 `Object` 类型的数据,这意味着在使用集合时,程序员必须进行强制类型转换。这种转换可能导致 `ClassCastException`,增加了代码的脆弱性。泛型的...

    java反射,获取所有属性、方法以及List集合类

    例如,`List&lt;?&gt;`的`Class`类型是`java.util.List`,这意味着你不能直接获取泛型的实际类型参数。然而,你可以通过类型检查和转换来操作List中的元素。 5. 访问私有成员: 对于私有字段和方法,可以使用`...

    反射与泛型

    在本主题中,我们将深入探讨如何通过反射获取泛型参数,并利用这些信息创建对象。 首先,让我们了解什么是反射。反射是Java提供的一种强大的工具,它允许我们在运行时检查类、接口、字段和方法的信息。通过反射,...

    Java泛型类型擦除后的补偿

    - 反射API在泛型类型擦除后仍然能获取到泛型信息,这主要通过泛型类的类型参数的实际类型参数化实例(TypeToken)来实现。 - 这使得在运行时可以进行一些泛型相关的操作,如创建参数化的类实例。 总结来说,Java...

    myreflect.rar 反射和泛型使用源码

    总的来说,Java反射提供了运行时的动态能力,而泛型则在编译时提高了类型安全性。结合使用,开发者可以构建更加灵活且安全的系统。通过学习和实践压缩包中的源代码,你将能够更熟练地运用这两个工具解决实际问题。

    java 通过反射获取类上注解,方法上注解,注解里的值及方法参数

    本教程将深入探讨如何通过反射获取类、方法上的注解以及注解中的值和方法参数。 1. **注解的定义与使用** 注解以`@`符号开头,后面跟着注解的类型。例如,`@Override`表示方法重写,`@Deprecated`表示某个功能已...

    java泛型反射注解

    先说一下遇到的问题:通过使用GSON泛型进行报文转换的时候想要对部分关键字段加密,...解决过程:首先通过反射获取到bean下的对象名称。 对象名称获取到了之后需要获取对应的值 对值进行加密,然后再重新赋值到该对象

    Java反射、泛型和注解实战之Spring核心注入IOC的实现

    通过这个实战项目,你可以深入理解Java反射、泛型和注解的用法,并且了解到如何利用它们构建一个基本的依赖注入系统,这将有助于你更好地理解和使用Spring框架。同时,这样的实践也有助于提升你的编程技能,使你能够...

    反射处理java泛型

    当我们声明了一个泛型的接口或类,或需要一个子类继承至这个泛型类,而我们又希望利用反射获取这些泛型参数信息。这是本文将要介绍的ReflectionUtil是为了解决这类问题的辅助工具类,为java.lang.reflect标准库的...

    Java使用反射来获取泛型信息示例

    通过这个实例,我们可以看到,使用Java反射机制来获取泛型信息是非常方便的,只要我们使用ParameterizedType对象来获取泛型参数的信息。同时,我们也可以看到,使用反射机制可以获取到类中的字段、方法和构造函数等...

    java反射全解(反射原理+反射API详解+反射与数组+反射与泛型+反射源码与性能开销+反射优缺点+反射与内省)

    泛型是 Java 语言中的一种类型参数机制,反射机制可以动态地获取泛型的信息和调用泛型的方法。 反射源码与性能开销是指在反射机制中如何影响性能。反射机制可以动态地获取类的信息和调用对象的方法,但是它也存在...

    反射泛型

    如果类具有泛型参数,我们可以使用反射来获取实际的泛型类型,从而更好地理解实例化的对象。 2. **动态调用方法**:使用`Class.getMethod()`或`Class.getDeclaredMethod()`获取方法对象,然后调用`invoke()`方法...

Global site tag (gtag.js) - Google Analytics