二、 ParameterizedType 参数化的类型,顾名思义,就是给一个类型传递了类型参数,例 List<Contract> List接口被传递了Contract类型参数,那么类型List<Contract>就是ParameterizedType,它可以做属性的类型,做方法参数或返回值的类型,也可以做泛型声明的上边界。 例如 public class GenericClass<T extends List<Contract>>里的List<Contract>。由于泛型声明可以声明多个泛型参数,所以,参数化的类型也可以传入多个类型参数,多个类型参数用,隔开。例如著名的Map定义的泛型参数是K和V 可以传入Map<String,Contract>等等.如果属性或方法参数声明的数据给类型传递了类型参数,则field.getGenericType method.getGenericParameterType返回Type 就是 instanceof ParameterizedType. ptype.getActualTypeArguments() :Type[]返回每个传入的类型参数,返回值的长度取决于泛型声明时声明了几个形式泛型参数。本文提出的问题便是基于这一点来尝试解决的。ptype.getRawType() type返回的是<>外的类型 即接收类型参数的类型,如List,Map.
三、WildcardType 这种类型用来处理参数化类型里,对类型参数范围的描述。例如一个方法的泛型参数是 Map<? extends Number,? super Contract>,此时 <> 里用逗号隔开两个对象都是WildcardType的实例。对每一个WildcardType对象(验证type instanceof WildcardType==true) wtype.getUpperBounds():Type[]返回上边界类型(默认是Object.class),wtype.getLowerBounds():Type[]返回下边界类型。
说了这么多,逻辑太绕了,本来就很难说清楚。只有多测试多使用才能体会到。下面给一个我写的方法,这个方法用来访问一个Collection接口类型的Field,假定该Field使用了泛型,然后返回Collection的类型参数具体是什么,即返回客户类指定的集合元素的类型。注意,的确只能在运行时才能确定具体类型,本方法只能获得泛型的边界,然后用上边界类型来构造对象。如果一个使用了泛型的属性刚好就像List<Contract>一样,那么读取到Contract.class是轻而易举的,因为这个泛型参数的边界是固定的。
public Class getGenericTypeBounds(Field field)
throws TypeResolveException{
Type type = field.getGenericType();
if(type instanceof Class){
throw new TypeResolveException(field.getDeclaringClass().getName()+"属性"
+field.getName()+" 没有使用泛型或者 使用了rawtype但是没有指定泛型实参。");
}
else if(type instanceof GenericArrayType){
type = ((GenericArrayType)type).getGenericComponentType();
}
else if(type instanceof TypeVariable<?>){
type = ((TypeVariable<?>)type).getBounds()[0];
}
else if(type instanceof ParameterizedType){
ParameterizedType ptype = (ParameterizedType)type;
Type[] types = ptype.getActualTypeArguments();
if(types==null || types.length==0){
throw new TypeResolveException(field.getDeclaringClass().getName()+"的集合属性"
+field.getName()+" 所引用的泛型类型没有指定泛型实参取值。");
}
if(types.length>1){
throw new TypeResolveException(field.getDeclaringClass().getName()+"的集合属性"
+field.getName()+" 所引用的泛型类型 指定的泛型实参取值多于1个。");
}
type = ptype.getActualTypeArguments()[0];//只有这个方法的返回值才可能是 WildcardType
}
while(!(type instanceof Class)){
if(type instanceof WildcardType){
type = ((WildcardType)type).getUpperBounds()[0];
}
else if(type instanceof TypeVariable<?>){
type = ((TypeVariable<?>)type).getBounds()[0];
}
else if(type instanceof ParameterizedType){
ParameterizedType ptype = (ParameterizedType)type;
Type[] types = ptype.getActualTypeArguments();
if(types==null||types.length==0){
return Object.class;
}
if(types.length>1){
throw new TypeResolveException(field.getDeclaringClass().getName()+"的集合属性"
+field.getName()+"引用到的泛型"+ptype+"的实参数量多于1个");
}
type = ptype.getActualTypeArguments()[0];
}
else if(type instanceof GenericArrayType ){
type = ((GenericArrayType)type).getGenericComponentType();
}
}
return (Class)type;
}
分享到:
相关推荐
对java泛型以及反射机制进行原理和应用上的讲解,帮助初学者对这两个概念进行更轻松的掌握
在Java中运用反射+泛型,实现数据库的动态增删改查等功能,可以是Mysql, 也可以是SQL Server,oracle 也行。本代码是支持SQL Server和oracle的。
Java泛型和反射机制
基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码....
java的基于泛型+反射的通用DAO例子,原创,没事写着玩的,请多指教哈。。。
反射和泛型是一种重要的解决途径。 此代码是一个生成泛型对象的类。 比如: Pool<Point> pool = new Pool(){}; Point p = pool.get(x, y); //在此构造Point对象 ... pool.put(p); 希望能帮助那些为查找泛型构造器、...
Java试题-3:反射和泛型的综合应用 Java反射 泛型都是比较高级的应用技术
详细介绍了JAVA泛型和反射,对学习JAVA很有帮助哦!!!!
Java基础入门(四)-泛型、反射、注解
反射泛型完美版分页.rar
Java 反射与泛型教程 资源为视频教程资源 希望对你的 Java 学习有所帮助。
先说一下遇到的问题:通过使用GSON泛型进行报文转换的时候想要对部分关键字段加密,发现在封装好的方法中,对个别字段的加密满足不了。 解决过程:首先通过反射获取到bean下的对象名称。 对象名称获取到了之后需要...
综合运用Java反射、泛型和注解实现的类似Spring的核心注入
NULL 博文链接:https://zouwu85.iteye.com/blog/801921
主要介绍了Java泛型的用法及T.class的获取过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?...在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。
它提供了便捷的访问泛型对象类型(java.reflect.Type)的反射方法。 本文假设你已经了解java反射知识,并能熟练的应用。如果还不了解java反射知识,那么你可以先移步到Oracel反射课程,这可能是你开始学习反射的好...
java泛型+反射使用的源码,比较详细,欢迎下载