java 学习笔记--利用反射实现自定义toString()的工具类

引用自java核心技术卷I

一个toString的工具方法,通过java反射来实现:

package com.handkoo.chap5;

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 object){
		// 如果为null,就返回一个null字符串
		if(object==null){
			return "null";
		}
		// 记录该对象是否被访问过
		if(visited.contains(object)){
			return "...";
		}
		// 标记该对象被访问
		visited.add(object);
		// 获取class实例
		Class cl = object.getClass();
		// 如果是String的类直接返回string
		if(cl == String.class){
			return (String) object;
		}
		// 如果是一个数组类型
		if(cl.isArray()){
			// 获取该数组的数据类型->开始数组
			String r = cl.getComponentType()+"[]{";
			// 遍历该数组
			for(int i = 0;i<Array.getLength(object);i++){
				// 如果不是第一个需要输入,(方便查看)
				if(i>0){
					r+=",";
				}
				// 获取当前数组的对象
				Object val = Array.get(object, i);
				// 判断是否为基本类型,如果不是基本类型还要继续遍历(递归)
				if(cl.getComponentType().isPrimitive()){
					// 如果是基本类型就添加到字符串
					r+=val;
				}else{
					// 递归(使用+=继续拼接字符串)
					r+=toString(val);
				}
			}
			//->闭合数组字符串
			return r+"}";
		}		
		// 如果不是数组
		// 获取类的名称
		String r = cl.getName();
		do{
			// 开始拼接字符串
			r+="[";
			// 获取所有的实力域
			Field[] fields = cl.getDeclaredFields();
			// 设置所有的于可以访问(由于有的类中的属性字段为private的类型)
			AccessibleObject.setAccessible(fields, true);
			// 遍历该field
			for(Field f:fields){
				// 判断如果是非静态的属性
				if(!Modifier.isStatic(f.getModifiers())){
					// 如果不是第一个[,使用,号隔开,目的是方便查看
					if(!r.endsWith("[")){
						r+=",";
					}
					// 获取名称,并拼接字符串
					r+= f.getName()+"=";
					try {
						// 获取属性的数据类型
						Class t = f.getType();
						// 获取该属性的数据值
						Object val = f.get(object);
						// 判断是否为基本类型,如果是拼接字符,如果不是,就再次递归(同上)
						if(t.isPrimitive()){
							r+=val;
						}else{
							r+=toString(val);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
			// 结束标记
			r+="]";
			// 获取到超类,一直向上遍历
			cl = cl.getSuperclass();
		}while(cl!=null); 
		// 返回最终的字符串
		return r;
	}
}

测试代码:

package com.handkoo.chap5;

import java.util.ArrayList;

public class ObjectAnalyzerTest {
	public static void main(String[] args){
		ArrayList<Integer> squares = new ArrayList<>();
		for(int i = 0;i<=5;i++){
			squares.add(i*i);
		}
		System.out.println(new ObjectAnalyzer().toString(squares));
	}
}

运行的结果:

java.util.ArrayList
    [
        elementData=class java.lang.Object[]{
            java.lang.Integer[value=0][][],
            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
        },
        size=6
    ]
    [modCount=6]
    []
    []

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值