参考fastjson中的获取泛型类中真实类型的代码片段,在org.nutz.lang.reflect.ReflectTool类中增加如下方法:
/**
* 泛型类clazz,field字段的真实class对象.
* @param clazz 泛型class
* @param field 字段
* @return
*/
public static Class<?> getGenericFieldType(Class<?> clazz, Field field) {
Type fieldType = field.getGenericType();
return getRealGenericClass(clazz, fieldType);
}
/**
* 获取泛型类中type变量对应的真实class
* @param clazz 泛型基类.
* @param type 泛型基类中的某个type
* @return
*/
public static Class<?> getRealGenericClass(Class<?> clazz, Type type) {
if(type instanceof TypeVariable) {
TypeVariable<?> tv = (TypeVariable<?>) type;
Type genericFieldType = getInheritGenericType(clazz, tv);
if (genericFieldType != null) {
return Lang.getTypeClass(genericFieldType);
}
}
return Lang.getTypeClass(type);
}
/**
* 获取泛型类中type对应的真实Type
* @param clazz
* @param type
* @return
*/
public static Type getInheritGenericType(Class<?> clazz, Type type) {
if(type instanceof TypeVariable) {
TypeVariable<?> tv = (TypeVariable<?>) type;
return getInheritGenericType(clazz, tv);
}else {
return type;
}
}
/**
* 获取泛型类clazz中某个TypeVariable对应的真实Type.
* @param clazz
* @param tv
* @return
*/
public static Type getInheritGenericType(Class<?> clazz, TypeVariable<?> tv) {
Type type = null;
GenericDeclaration gd = tv.getGenericDeclaration();
do {
type = clazz.getGenericSuperclass();
if (type == null) {
return null;
}
if (type instanceof ParameterizedType) {
ParameterizedType ptype = (ParameterizedType) type;
Type rawType = ptype.getRawType();
boolean eq = gd.equals(rawType) || (gd instanceof Class && rawType instanceof Class && ((Class) gd).isAssignableFrom((Class) rawType));
if (eq) {
TypeVariable<?>[] tvs = gd.getTypeParameters();
Type[] types = ptype.getActualTypeArguments();
for (int i = 0; i < tvs.length; i++) {
if (tv.equals(tvs[i])) {
return types[i];
}
}
return null;
}
}
clazz = Lang.getTypeClass(type);
} while (type != null);
return null;
}
然后修改org.nutz.lang.Lang#map2Object方法中的
//Class<?> ft = field.getType();
Class<?> ft = ReflectTool.getGenericFieldType(toType, field);
修改org.nutz.lang.inject.InjectBySetter#inject方法
Type realType = ReflectTool.getInheritGenericType(obj.getClass(), type);
Class<?> realValuType = Lang.getTypeClass(realType);
if (isMapCollection && value != null && value instanceof String) {
v = Json.fromJson(realType, value.toString());
} else {
v = Castors.me().castTo(value, realValuType);
}
这样测试时可以正常设置对应的值