java反射獲取聚合<List>屬性欄位
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