java 學習筆記--利用反射實現自定義toString()的工具類

xiaopengyaonixi發表於2016-10-13

引用自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]
    []
    []

相關文章