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][]
    []
posted @ 2021-10-16 14:29  Frontierone  阅读(107)  评论(0编辑  收藏  举报