反射应用--通用的toString方法,泛型数组代码

反射应用 - toString方法/泛型数组代码

  我们常用的toString方法都是显式地调用其域,当需要时,要在类中重写toString方法(基本上一个类一个),而通用toString方法什么都不需要知道,直接调用即可。

  泛型数组代码不需要记,是java.util.Arrays类中copyOf(T[] original, int newLength) 方法实现底层中使用了反射机制,这里介绍了一下而已。

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> vistied =new ArrayList<>();
	
	public String toString(Object obj) {
		if (obj == null) return "null";   //对象为null,返回“null”
		if (vistied.contains(obj)) return "...";  //
		vistied.add(obj);
		
		Class<? extends Object> c1 = obj.getClass();
		if(c1 == String.class) return (String) obj; //对象类型为字符串,直接打印
		
		//对象类型为数组
		if(c1.isArray()) { 
			String r = c1.getComponentType() + "[]{";  //getComponentType返回数组类型
			for(int i=0;i<Array.getLength(obj);i++) {  //getLength返回数组长度
				if(i>0) r +=",";  //逗号分隔元素
				Object val =Array.get(obj, i); //返回数组中指定索引的值
				if(c1.getComponentType().isPrimitive()) //若数组中类型为基本类型,直接添加于字符串r中
					r += val;  
				else 
					r += toString(val); //递归,执行本方法中‘对象类型非数组’部分
				
			}
			return r+"}";
		}
		
		//对象类型为非数组
		String r = c1.getName(); //获取对象所属的类
		do {
			r += "[";
			Field[] fields = c1.getDeclaredFields(); //获取本类所有域
			AccessibleObject.setAccessible(fields, true); //开放域的访问限制
			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(obj);  //获取域值
						if(t.isPrimitive()) 
							r+= val; //若域类型为基本数据类型,直接加入域值
						else
							r += toString(val); //若域类型为对象,调用本方法
					}catch(Exception e){
						e.printStackTrace();
					}
				}
			}
			r += "]";
			c1 = c1.getSuperclass();  //开始获取超类的域
		}while(c1 != null);
		
		return r;
	}
	
	
	//泛型数组代码
	public static Object copyOf(Object a,int newLength) { //参数类型定义为Object,而不可以是Object[],是因为基本类型数组不可转换为Object[],但可以是Object
		Class<? extends Object> c1 = a.getClass();
		if(!c1.isArray()) return null;  //不是数组,返回null
		Class<?> componentType = c1.getComponentType();  //获取数组类型
		int length = Array.getLength(a); //获取数组长度
		Object newArray = Array.newInstance(componentType, newLength);
		System.arraycopy(a, 0, newArray, 0, Math.min(length,newLength));
		return newArray;
		
	}
}

//调用toString方法
Employee em = new Employee(2,3,4,5);
System.out.println(new ObjectAnalyzer().toString(em));
java.lang.reflect.Array 相关API 表
返回类型方法名和参数解释
static Objectget(Object array, int index)返回存储在指定index上给定数组的内容
static xxxxgetXxxx(Object array, int index)若index索引处的类型为基本类型,可直接调用相关方法,那样得到的结果就不用强转了
static voidset(Object array, int index, Object value)将新值存储到给定位置上的给定数组中
static voidsetXxxx(Object array, int index, Object value)若index索引处的类型为基本类型,可直接调用相关方法
static intgetLength(Object array)返回指定数组对象的长度
static ObjectnewInstance(Class<?> componentType, int length)返回具有给定类型,给定长度的新数组
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值