`
xuji
  • 浏览: 11260 次
社区版块
存档分类
最新评论

java 反射 泛型机制 获得泛型的实际类型(二)

阅读更多
  
   二、 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;
}
  
 
  

  
1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics