`

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

    博客分类:
  • 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就根据泛型拿到,我们需要转型的对象。 

代码片段如下 

Java代码  收藏代码
 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代码  收藏代码
System.out.println(String.class.isAssignableFrom(Object.class));     
2.//打印true   
    AA.class.isAssignableFrom(BB.class)的作用是判定AA表示的类或接口是否同参数BB指定的类表示的类或接口相同,或AA是否是BB的父类。 
Java代码  收藏代码
  System.out.println( String.class.isAssignableFrom(Object.class) ) ;       false  
System.out.println( Object.class.isAssignableFrom(Object.class) );       true  
System.out.println( Object.class.isAssignableFrom(String.class) );        true  
String ss = "";     
System.out.println( ss instanceof Object );                                            true  
Object o = new   Object();  
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代码  收藏代码
  public class  ClassA <T>{       
      private T obj;       
      public void setObject(T obj) {      this.obj = obj;  }     
      public T getObject() {    return obj;   }       
}    


         2.Test.java 

Java代码  收藏代码
   
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 * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class

    提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class,java * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class,java * 反射工具类. 提供调用getter/...

    java反射与泛型综合例子

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

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

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

    java 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class

    提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实...

    Java-Java反射与泛型教程

    2. **类型擦除**: 泛型在编译后会进行类型擦除,因此在运行时无法直接获取泛型类型信息。但泛型可以提供编译时的类型检查。 3. **通配符**: 通配符用于表示对类型的一般限制,如`?`表示任何类型,`? extends Number...

    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 通过反射获取类上注解,方法上注解,注解里的值及方法参数

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

    Java基础入门四泛型反射注解.pdf

    Java基础入门系列是帮助初学者掌握Java编程的重要学习材料,本篇主要介绍了泛型、反射和注解这三大高级特性。 泛型是Java SE 5版本引入的一个新特性,它的主要目的是允许在使用类、接口和方法时能够引用到任何类型...

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

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

    Java泛型类型擦除后的补偿

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

    java泛型反射注解

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

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

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

    反射处理java泛型

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

Global site tag (gtag.js) - Google Analytics