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]
[]
[]
相關文章
- Java學習筆記--反射Java筆記反射
- Java學習筆記之自定義異常Java筆記
- Java學習筆記系列-反射Java筆記反射
- Java學習筆記7(Java常用類庫與工具 )Java筆記
- JAVA核心技術學習筆記--反射Java筆記反射
- Java註解與反射學習筆記Java反射筆記
- 筆記3:自定義註解的實現筆記
- java反射之動態代理學習筆記Java反射筆記
- Go 反射 學習筆記Go反射筆記
- 關於SQLServer2005的學習筆記——自定義分組的實現SQLServer筆記
- iOS學習筆記--PresentedVC自定義彈窗iOS筆記
- 【JAVA】自定義類載入器實現類隔離Java
- Java 實現音訊新增自定義時長靜音(附程式碼) | Java工具類Java音訊
- java學習筆記(包裝類)Java筆記
- JAVA的反射機制==>用反射分析類的實現Java反射
- 學習筆記----快速排序的java實現及其改良筆記排序Java
- Pytest學習筆記6-自定義標記mark筆記
- Java學習筆記之類和物件Java筆記物件
- 自定義實現Complex類
- 註解和反射學習筆記反射筆記
- Java筆記-反射Java筆記反射
- java學習 -- 利用類的反射和泛型自己動手寫jdbc封裝小類庫Java反射泛型JDBC封裝
- Laravel學習筆記之Artisan命令生成自定義模板的方法Laravel筆記
- C#關於List<T>的自定義排序學習筆記C#排序筆記
- 步步學習自定義View:Hencoder 精簡版學習筆記(一)View筆記
- 《Java核心技術 卷I》學習筆記10:使用預定義類Java筆記
- 一個工具類實現自定義Tablayout的下劃線寬度TabLayout
- Java學習筆記之介面和抽象類Java筆記抽象
- 反射+Class類方法_利用反射分析類的能力反射
- Java筆記-Java反射(二)Java筆記反射
- 【Java 反射學習】Java 反射基礎Java反射
- [Java 反射學習] Java 反射基礎Java反射
- Java學習:反射Java反射
- Java學習_反射Java反射
- Java反射學習Java反射
- Unity 熱更--AssetBundle學習筆記 1.0【AB包資源載入工具類的實現】Unity筆記
- Java的自定義異常類Java
- Java自定義Annotation,通過反射解析AnnotationJava反射