• 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][]
        []
    
    埋骨何须桑梓地,人生无处不青山
  • 相关阅读:
    软件测试常见概念
    Apollo简介及工作原理
    bug的编写技巧与级别划分
    native与H5优缺点及H5测试
    优惠券测试
    go语言-for循环
    go语言-流程控制--if
    go语言-二进制与位运算
    cookie和session
    AJAX
  • 原文地址:https://www.cnblogs.com/ACMerszl/p/15414142.html
Copyright © 2020-2023  润新知