反射應用--通用的toString方法,泛型陣列程式碼
阿新 • • 發佈:2021-01-28
反射應用 - 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));
返回型別 | 方法名和引數 | 解釋 |
---|---|---|
static Object | get(Object array, int index) | 返回儲存在指定index上給定陣列的內容 |
static xxxx | getXxxx(Object array, int index) | 若index索引處的型別為基本型別,可直接呼叫相關方法,那樣得到的結果就不用強轉了 |
static void | set(Object array, int index, Object value) | 將新值儲存到給定位置上的給定陣列中 |
static void | setXxxx(Object array, int index, Object value) | 若index索引處的型別為基本型別,可直接呼叫相關方法 |
static int | getLength(Object array) | 返回指定陣列物件的長度 |
static Object | newInstance(Class<?> componentType, int length) | 返回具有給定型別,給定長度的新陣列 |