zoukankan      html  css  js  c++  java
  • java反射之ObjectAnalyzer

    java反射之ObjectAnalyzer

    1 在运行时使用反射分析对象

    查看对象域的关键方法是Field类中的get方法,如果f是一个Field类型的对象,obj是某个包含f域的类的对象,f.get(obj)将放回一个对象,其值为obj域的当前值。

    Employee harry = new Employee("Harry Hacker", 35000, 10, 1, 1989);
    Class cl = harry.getClass();
    //    the class object representing Employee
    Field f = cl.getDeclaredField("name");
    //    the name field of the Employee class
    Object v = f.get(harry);
    //    the value of the name field of the harry object  ---> Harry Hacker
    

    2 分析ObjectAnalyzer类

    核心卷一的例子

    package objectAnalyzer;
    
    import java.util.ArrayList;
    
    public class ObjectAnalyzerTest {
        public static void main(String[] args) {
            ArrayList<Integer> squares = new ArrayList<>();
            for (int i = 1; i <= 5; i++) {
                squares.add(i * i);
            }
            System.out.println(new ObjectAnalyzer().toString(squares));
        }
    }
    
    
    package objectAnalyzer;
    
    import equals.Employee;
    
    import java.lang.reflect.AccessibleObject;
    import java.lang.reflect.Array;
    import java.lang.reflect.Field;
    import java.lang.reflect.Modifier;
    import java.util.ArrayList;
    
    public class ObjectAnalyzer {
        private ArrayList<Object> visited = new ArrayList<>();
    
        public String toString(Object obj) {
            if (obj == null) return "null";
            if (visited.contains(obj)) return "...";
            visited.add(obj);
            Class cl = obj.getClass();
            System.out.println("cl  " + cl + "@@@@@" + (cl.isArray()));
            if (cl == String.class) return (String) obj;
            if (cl.isArray()) {
                System.out.println("^^^^^^^^^");
                String r = cl.getComponentType() + "[]{";
                System.out.println("current :" + r);
                for (int i = 0; i < Array.getLength(obj); i++) {
                    if (i > 0) r += ",";
                    Object val = Array.get(obj, i);
                    System.out.println("#####" + cl.getComponentType() + "***" + cl.getComponentType().isPrimitive() + "&&&" + val);
                    if (cl.getComponentType().isPrimitive()) r += val;
                    else r += toString(val);
                }
                return r + "}";
            }
    
            System.out.println("**********");
            String r = cl.getName();
            do {
                r += "[";
                Field[] fields = cl.getDeclaredFields();
                AccessibleObject.setAccessible(fields, true);
                System.out.println("fields :" + fields.length);
                for (Field f : fields) {
                    System.out.println(f.getName() + "~~~~~~~");
                    if (!Modifier.isStatic(f.getModifiers())) {
                        System.out.println("r***"+ r);
                        if (!r.endsWith("[")) r += ",";
                        r += f.getName() + "=";
                        System.out.println("r***"+ r);
                        try {
                            Class t = f.getType();
                            Object val = f.get(obj);
                            System.out.println("!!!!!!!!!" + t);
                            if (t.isPrimitive()) r += val;
                            else r += toString(val);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        System.out.println("r***"+ r);
                    }
                }
                r += "]";
                cl = cl.getSuperclass();
                System.out.println(r + "$$$$$$$$$" + cl);
            } while (cl != null);
            System.out.println("Finished:  " + r);
            return r;
        }
    }
    
    
    -------------------------------------- 运行结果 ------------------------------------
        
    cl  class java.util.ArrayList@@@@@false
    **********
    fields :7
    serialVersionUID~~~~~~~
    DEFAULT_CAPACITY~~~~~~~
    EMPTY_ELEMENTDATA~~~~~~~
    DEFAULTCAPACITY_EMPTY_ELEMENTDATA~~~~~~~
    elementData~~~~~~~
    r***java.util.ArrayList[
    r***java.util.ArrayList[elementData=
    !!!!!!!!!class [Ljava.lang.Object;
    cl  class [Ljava.lang.Object;@@@@@true
    ^^^^^^^^^
    current :class java.lang.Object[]{
    #####class java.lang.Object***false&&&1
    cl  class java.lang.Integer@@@@@false
    **********
    fields :11
    MIN_VALUE~~~~~~~
    MAX_VALUE~~~~~~~
    TYPE~~~~~~~
    digits~~~~~~~
    DigitTens~~~~~~~
    DigitOnes~~~~~~~
    sizeTable~~~~~~~
    value~~~~~~~
    r***java.lang.Integer[
    r***java.lang.Integer[value=
    !!!!!!!!!int
    r***java.lang.Integer[value=1
    SIZE~~~~~~~
    BYTES~~~~~~~
    serialVersionUID~~~~~~~
    java.lang.Integer[value=1]$$$$$$$$$class java.lang.Number
    fields :1
    serialVersionUID~~~~~~~
    java.lang.Integer[value=1][]$$$$$$$$$class java.lang.Object
    fields :0
    java.lang.Integer[value=1][][]$$$$$$$$$null
    Finished:  java.lang.Integer[value=1][][]
    #####class java.lang.Object***false&&&4
    cl  class java.lang.Integer@@@@@false
    **********
    fields :11
    MIN_VALUE~~~~~~~
    MAX_VALUE~~~~~~~
    TYPE~~~~~~~
    digits~~~~~~~
    DigitTens~~~~~~~
    DigitOnes~~~~~~~
    sizeTable~~~~~~~
    value~~~~~~~
    r***java.lang.Integer[
    r***java.lang.Integer[value=
    !!!!!!!!!int
    r***java.lang.Integer[value=4
    SIZE~~~~~~~
    BYTES~~~~~~~
    serialVersionUID~~~~~~~
    java.lang.Integer[value=4]$$$$$$$$$class java.lang.Number
    fields :1
    serialVersionUID~~~~~~~
    java.lang.Integer[value=4][]$$$$$$$$$class java.lang.Object
    fields :0
    java.lang.Integer[value=4][][]$$$$$$$$$null
    Finished:  java.lang.Integer[value=4][][]
    #####class java.lang.Object***false&&&9
    cl  class java.lang.Integer@@@@@false
    **********
    fields :11
    MIN_VALUE~~~~~~~
    MAX_VALUE~~~~~~~
    TYPE~~~~~~~
    digits~~~~~~~
    DigitTens~~~~~~~
    DigitOnes~~~~~~~
    sizeTable~~~~~~~
    value~~~~~~~
    r***java.lang.Integer[
    r***java.lang.Integer[value=
    !!!!!!!!!int
    r***java.lang.Integer[value=9
    SIZE~~~~~~~
    BYTES~~~~~~~
    serialVersionUID~~~~~~~
    java.lang.Integer[value=9]$$$$$$$$$class java.lang.Number
    fields :1
    serialVersionUID~~~~~~~
    java.lang.Integer[value=9][]$$$$$$$$$class java.lang.Object
    fields :0
    java.lang.Integer[value=9][][]$$$$$$$$$null
    Finished:  java.lang.Integer[value=9][][]
    #####class java.lang.Object***false&&&16
    cl  class java.lang.Integer@@@@@false
    **********
    fields :11
    MIN_VALUE~~~~~~~
    MAX_VALUE~~~~~~~
    TYPE~~~~~~~
    digits~~~~~~~
    DigitTens~~~~~~~
    DigitOnes~~~~~~~
    sizeTable~~~~~~~
    value~~~~~~~
    r***java.lang.Integer[
    r***java.lang.Integer[value=
    !!!!!!!!!int
    r***java.lang.Integer[value=16
    SIZE~~~~~~~
    BYTES~~~~~~~
    serialVersionUID~~~~~~~
    java.lang.Integer[value=16]$$$$$$$$$class java.lang.Number
    fields :1
    serialVersionUID~~~~~~~
    java.lang.Integer[value=16][]$$$$$$$$$class java.lang.Object
    fields :0
    java.lang.Integer[value=16][][]$$$$$$$$$null
    Finished:  java.lang.Integer[value=16][][]
    #####class java.lang.Object***false&&&25
    cl  class java.lang.Integer@@@@@false
    **********
    fields :11
    MIN_VALUE~~~~~~~
    MAX_VALUE~~~~~~~
    TYPE~~~~~~~
    digits~~~~~~~
    DigitTens~~~~~~~
    DigitOnes~~~~~~~
    sizeTable~~~~~~~
    value~~~~~~~
    r***java.lang.Integer[
    r***java.lang.Integer[value=
    !!!!!!!!!int
    r***java.lang.Integer[value=25
    SIZE~~~~~~~
    BYTES~~~~~~~
    serialVersionUID~~~~~~~
    java.lang.Integer[value=25]$$$$$$$$$class java.lang.Number
    fields :1
    serialVersionUID~~~~~~~
    java.lang.Integer[value=25][]$$$$$$$$$class java.lang.Object
    fields :0
    java.lang.Integer[value=25][][]$$$$$$$$$null
    Finished:  java.lang.Integer[value=25][][]
    #####class java.lang.Object***false&&&null
    #####class java.lang.Object***false&&&null
    #####class java.lang.Object***false&&&null
    #####class java.lang.Object***false&&&null
    #####class java.lang.Object***false&&&null
    r***java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null}
    size~~~~~~~
    r***java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null}
    r***java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=
    !!!!!!!!!int
    r***java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5
    MAX_ARRAY_SIZE~~~~~~~
    java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5]$$$$$$$$$class java.util.AbstractList
    fields :1
    modCount~~~~~~~
    r***java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5][
    r***java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5][modCount=
    !!!!!!!!!int
    r***java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5][modCount=5
    java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5][modCount=5]$$$$$$$$$class java.util.AbstractCollection
    fields :1
    MAX_ARRAY_SIZE~~~~~~~
    java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5][modCount=5][]$$$$$$$$$class java.lang.Object
    fields :0
    java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5][modCount=5][][]$$$$$$$$$null
    Finished:  java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5][modCount=5][][]
    java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5][modCount=5][][]
    
    

    2.1 整体流程分析

    一.标记对象
    二.判断class是否是数组类
         if yes:
    	1.获取数组组件类型
    	2.遍历数组元素 
                判断是否是基本数据类型
    	      if yes:
    		添加到r后面
           	      else:
    		递归toString(val)
    	3.return r
    三.while循环 直到Object类
         1.获取cl的所有域
         2.解除安全管理器的控制
         3.遍历所有的域
    	 判断是否是非静态域
    	   if yes:
    	        1)域的变量名添加到r后面
    		2)获取域的类型 和 该域对应的值
    		3)判断类型是否是基本数据类型
                        if yes:
                              添加到r后面
      	            else:
      		          递归toString(val)
         4.cl = cl.getSuperclass() 往上走
    

    2.2 运行结果分析

    squars的类型是ArrayList
    ArrayList 
        非数组类型
        共7个域 第5个域elementData是非静态域 其类型为Object[]
    ----------(1)-------------------
    Object[]  
    	数组类型
    	获取数组组件类型为Integer
    ----------(2) -------------------
    Integer     
    	非数组类型
    	共11个域 第8个域value是非静态域 其类型为int 
    	遍历完Integer的所有域 变为Integer的父类Number
    ----------(3) -------------------
    Number    
    	非数组类型
    	共1个域 没有非静态域 变为Number的父类Object
    ----------(4) -------------------
    Object   
    	非数组类型
    	共0个域
    ----------(5) -------------------
    
    (1) java.util.ArrayList[elementData=
    
    (2) java.util.ArrayList[elementData=class java.lang.Object[]{
    
    (3) java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1]
    
    (4) java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][]
    
    (5) java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][]
        []
    
    埋骨何须桑梓地,人生无处不青山
  • 相关阅读:
    LeetCode Array Easy 414. Third Maximum Number
    LeetCode Linked List Medium 2. Add Two Numbers
    LeetCode Array Easy 283. Move Zeroes
    LeetCode Array Easy 268. Missing Number
    LeetCode Array Easy 219. Contains Duplicate II
    LeetCode Array Easy 217. Contains Duplicate
    LeetCode Array Easy 189. Rotate Array
    LeetCode Array Easy169. Majority Element
    LeetCode Array Medium 11. Container With Most Water
    LeetCode Array Easy 167. Two Sum II
  • 原文地址:https://www.cnblogs.com/ACMerszl/p/15414142.html
Copyright © 2011-2022 走看看