java反射获取聚合<List>属性字段

java反射获取聚合<List>属性字段

2016年09月30日 11:59:40 阅读数:7997 标签: javareflect 更多

个人分类: java

需要动态的传入一个Class的类型,然后反射到启动的List,根据List里定义的泛型,知道其中List的具体对象的各种属性。 

代码

 
  1. import java.lang.reflect.Field;

  2. import java.lang.reflect.ParameterizedType;

  3. import java.lang.reflect.Type;

  4. import java.util.ArrayList;

  5. import java.util.HashMap;

  6. import java.util.HashSet;

  7. import java.util.List;

  8. import java.util.Map;

  9. import java.util.Set;

  10.  
  11. import com.meyacom.ruleapp.dto.Ztree;

  12.  
  13. public class test {

  14.  
  15. public static void main(String[] args) throws ClassNotFoundException {

  16. Class<?> apply = Class.forName("com.chac.ruleapp.bom.ApplyTest");

  17. Field[] fields = apply.getFields();

  18. //获取所有属性

  19. List> allFieldList = getBomFields1(new ArrayList(), fields);

  20. for (List list : allFieldList) {

  21. System.out.println(list.toString());

  22. }

  23. }

  24.  
  25. protected static List> getBomFields(List chain, Field[] fields) {

  26. List> result = new ArrayList>();

  27. for (Field field : fields) {

  28. Class<?> fieldClass = field.getType();

  29. if (fieldClass.getName().startsWith("java")

  30. || fieldClass.getName().startsWith("javax")

  31. || fieldClass.getName().startsWith("com.sun")

  32. || fieldClass.getName().startsWith("boolean")

  33. || fieldClass.getName().startsWith("double")

  34. || fieldClass.getName().startsWith("int")) {

  35. List endChain = new ArrayList(chain);

  36. endChain.add(field);

  37. result.add(endChain);

  38. continue;

  39. } else {

  40. List thisChain = new ArrayList(chain);

  41. thisChain.add(field);

  42. result.addAll(getBomFields(new java.util.ArrayList(

  43. thisChain), fieldClass.getDeclaredFields()));

  44. }

  45. }

  46. return result;

  47. }

  48. public static List> getBomFields1(List chain,

  49. Field[] fields) {

  50. List> result = new ArrayList>();

  51. for (Field field : fields) {

  52. Class<?> fieldClass = field.getType();

  53. if (fieldClass.isPrimitive()

  54. || fieldClass.getName().startsWith("java.lang")

  55. || fieldClass.getName().startsWith("java.util.Date")

  56. || fieldClass.getName().startsWith("javax")

  57. || fieldClass.getName().startsWith("com.sun")

  58. || fieldClass.getName().startsWith("sun")

  59. || fieldClass.getName().startsWith("boolean")

  60. || fieldClass.getName().startsWith("double")

  61. || fieldClass.getName().startsWith("int")) {

  62. List endChain = new ArrayList(chain);

  63. endChain.add(field);

  64. result.add(endChain);

  65. continue;

  66. } else {

  67. if (fieldClass.isAssignableFrom(List.class)) // 【2】

  68. {

  69. Type fc = field.getGenericType(); // 关键的地方,如果是List类型,得到其Generic的类型

  70. if (fc instanceof ParameterizedType) // 【3】如果是泛型参数的类型

  71. {

  72. ParameterizedType pt = (ParameterizedType) fc;

  73. Class genericClazz = (Class) pt.getActualTypeArguments()[0]; // 【4】

  74. if ( genericClazz.getName().startsWith("java.lang") //设置list的终止类型

  75. || genericClazz.getName().startsWith("java.util.Date")

  76. || genericClazz.getName().startsWith("javax")

  77. || genericClazz.getName().startsWith("com.sun")

  78. || genericClazz.getName().startsWith("sun")

  79. || genericClazz.getName().startsWith("boolean")

  80. || genericClazz.getName().startsWith("double")

  81. || genericClazz.getName().startsWith("int")) {

  82. continue;

  83. }

  84. //System.out.println(genericClazz);

  85. // 得到泛型里的class类型对象。

  86. List thisChain = new ArrayList(chain);

  87. // System.out.println(chain);

  88. thisChain.add(field); //!!

  89. result.addAll(getBomFields1(new ArrayList(thisChain), genericClazz.getDeclaredFields()));

  90. }

  91. } else {

  92. List thisChain = new ArrayList(chain);

  93. thisChain.add(field);

  94. result.addAll(getBomFields1(new ArrayList(thisChain),

  95. fieldClass.getDeclaredFields()));

  96. }

  97.  
  98. }

  99. }

  100. return result;

  101. }

其中针对List类型的单独判断参考一下别人的代码片段如下 

  1.  Field[] fs = clazz.getDeclaredFields(); // 得到所有的fields  
  2.   
  3. for(Field f : fs)   
  4. {   
  5.     Class fieldClazz = f.getType(); // 得到field的class及类型全路径  
  6.   
  7.     if(fieldClazz.isPrimitive())  continue;  //【1】 //判断是否为基本类型  
  8.   
  9.     if(fieldClazz.getName().startsWith("java.lang")) continue; //getName()返回field的类型全路径;  
  10.   
  11.     if(fieldClazz.isAssignableFrom(List.class)) //【2】  
  12.     {   
  13.              Type fc = f.getGenericType(); // 关键的地方,如果是List类型,得到其Generic的类型  
  14.   
  15.              if(fc == null) continue;  
  16.   
  17.              if(fc instanceof ParameterizedType) // 【3】如果是泛型参数的类型   
  18.             {   
  19.                    ParameterizedType pt = (ParameterizedType) fc;  
  20.   
  21.                    Class genericClazz = (Class)pt.getActualTypeArguments()[0]; //【4】 得到泛型里的class类型对象。  
  22.   
  23.                    m.put(f.getName(), genericClazz);  
  24.   
  25.                    Map<String, Class> m1 = prepareMap(genericClazz);  
  26.   
  27.                    m.putAll(m1);   
  28.              }   
  29.       }   
  30. }  




【解释】: 
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

猜你喜欢

转载自blog.csdn.net/evilcry2012/article/details/82120909