java反射获取聚合<List>属性字段
2016年09月30日 11:59:40 阅读数:7997 标签: javareflect 更多
个人分类: java
需要动态的传入一个Class的类型,然后反射到启动的List,根据List里定义的泛型,知道其中List的具体对象的各种属性。
代码
-
import java.lang.reflect.Field;
-
import java.lang.reflect.ParameterizedType;
-
import java.lang.reflect.Type;
-
import java.util.ArrayList;
-
import java.util.HashMap;
-
import java.util.HashSet;
-
import java.util.List;
-
import java.util.Map;
-
import java.util.Set;
-
import com.meyacom.ruleapp.dto.Ztree;
-
public class test {
-
public static void main(String[] args) throws ClassNotFoundException {
-
Class<?> apply = Class.forName("com.chac.ruleapp.bom.ApplyTest");
-
Field[] fields = apply.getFields();
-
//获取所有属性
-
List> allFieldList = getBomFields1(new ArrayList(), fields);
-
for (List list : allFieldList) {
-
System.out.println(list.toString());
-
}
-
}
-
protected static List> getBomFields(List chain, Field[] fields) {
-
List> result = new ArrayList>();
-
for (Field field : fields) {
-
Class<?> fieldClass = field.getType();
-
if (fieldClass.getName().startsWith("java")
-
|| fieldClass.getName().startsWith("javax")
-
|| fieldClass.getName().startsWith("com.sun")
-
|| fieldClass.getName().startsWith("boolean")
-
|| fieldClass.getName().startsWith("double")
-
|| fieldClass.getName().startsWith("int")) {
-
List endChain = new ArrayList(chain);
-
endChain.add(field);
-
result.add(endChain);
-
continue;
-
} else {
-
List thisChain = new ArrayList(chain);
-
thisChain.add(field);
-
result.addAll(getBomFields(new java.util.ArrayList(
-
thisChain), fieldClass.getDeclaredFields()));
-
}
-
}
-
return result;
-
}
-
public static List> getBomFields1(List chain,
-
Field[] fields) {
-
List> result = new ArrayList>();
-
for (Field field : fields) {
-
Class<?> fieldClass = field.getType();
-
if (fieldClass.isPrimitive()
-
|| fieldClass.getName().startsWith("java.lang")
-
|| fieldClass.getName().startsWith("java.util.Date")
-
|| fieldClass.getName().startsWith("javax")
-
|| fieldClass.getName().startsWith("com.sun")
-
|| fieldClass.getName().startsWith("sun")
-
|| fieldClass.getName().startsWith("boolean")
-
|| fieldClass.getName().startsWith("double")
-
|| fieldClass.getName().startsWith("int")) {
-
List endChain = new ArrayList(chain);
-
endChain.add(field);
-
result.add(endChain);
-
continue;
-
} else {
-
if (fieldClass.isAssignableFrom(List.class)) // 【2】
-
{
-
Type fc = field.getGenericType(); // 关键的地方,如果是List类型,得到其Generic的类型
-
if (fc instanceof ParameterizedType) // 【3】如果是泛型参数的类型
-
{
-
ParameterizedType pt = (ParameterizedType) fc;
-
Class genericClazz = (Class) pt.getActualTypeArguments()[0]; // 【4】
-
if ( genericClazz.getName().startsWith("java.lang") //设置list的终止类型
-
|| genericClazz.getName().startsWith("java.util.Date")
-
|| genericClazz.getName().startsWith("javax")
-
|| genericClazz.getName().startsWith("com.sun")
-
|| genericClazz.getName().startsWith("sun")
-
|| genericClazz.getName().startsWith("boolean")
-
|| genericClazz.getName().startsWith("double")
-
|| genericClazz.getName().startsWith("int")) {
-
continue;
-
}
-
//System.out.println(genericClazz);
-
// 得到泛型里的class类型对象。
-
List thisChain = new ArrayList(chain);
-
// System.out.println(chain);
-
thisChain.add(field); //!!
-
result.addAll(getBomFields1(new ArrayList(thisChain), genericClazz.getDeclaredFields()));
-
}
-
} else {
-
List thisChain = new ArrayList(chain);
-
thisChain.add(field);
-
result.addAll(getBomFields1(new ArrayList(thisChain),
-
fieldClass.getDeclaredFields()));
-
}
-
}
-
}
-
return result;
-
}
其中针对List类型的单独判断参考一下别人的代码片段如下
- 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
参考http://lorry1113.iteye.com/blog/973903
http://www.360doc.com/content/11/1231/14/1954236_176297236.shtml