| 類別 | 常用方法 | 用途 |
|---|---|---|
| Class | getDeclaredFields()、getMethods()、getConstructors()、newInstance() | 獲取類別結構、創建實例 |
| Field | getName()、getType()、setAccessible(true)、set(obj, val)、get(obj) | 操作成員變數(含 private) |
| Method | getName()、getReturnType()、getParameterTypes()、invoke(obj, args) | 呼叫方法(含 private) |
public class ReflectionUtils {
/** 獲取所有欄位名與型別 */
public static List<FieldInfo> getFieldInfos(Object obj) {
List<FieldInfo> list = new ArrayList<>();
for (Field f : obj.getClass().getDeclaredFields()) {
f.setAccessible(true);
list.add(new FieldInfo(f.getName(), f.getType(), f));
}
return list;
}
/** 設值:支援基本型別、String、Date、包裝型別自動轉換 */
public static void setFieldValue(Object obj, String fieldName, Object value) {
try {
Field f = obj.getClass().getDeclaredField(fieldName);
f.setAccessible(true);
// 型別適配:字串轉目標型別
Object converted = convertValue(value, f.getType());
f.set(obj, converted);
} catch (Exception e) {
throw new RuntimeException("設值失敗: " + fieldName, e);
}
}
/** 取值 */
public static Object getFieldValue(Object obj, String fieldName) {
try {
Field f = obj.getClass().getDeclaredField(fieldName);
f.setAccessible(true);
return f.get(obj);
} catch (Exception e) {
throw new RuntimeException("取值失敗: " + fieldName, e);
}
}
/** 呼叫 Getter */
public static Object invokeGetter(Object obj, String fieldName) {
String getter = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
try {
Method m = obj.getClass().getMethod(getter);
return m.invoke(obj);
} catch (Exception e) {
throw new RuntimeException("Getter 呼叫失敗: " + getter, e);
}
}
/** 字串自動轉換為目標型別 */
private static Object convertValue(Object value, Class<?> targetType) {
if (value == null) return null;
if (targetType.isInstance(value)) return value;
if (targetType == String.class) return value.toString();
if (targetType == int.class || targetType == Integer.class) return Integer.valueOf(value.toString());
if (targetType == long.class || targetType == Long.class) return Long.valueOf(value.toString());
if (targetType == double.class || targetType == Double.class) return Double.valueOf(value.toString());
if (targetType == boolean.class || targetType == Boolean.class) return Boolean.valueOf(value.toString());
if (targetType == Date.class) {
// 可擴充支援多種日期格式
return new Date(Long.valueOf(value.toString()));
}
throw new IllegalArgumentException("不支援的型別: " + targetType);
}
static class FieldInfo {
String name; Class<?> type; Field field;
FieldInfo(String n, Class<?> t, Field f) { name=n; type=t; field=f; }
}
}
public class User {
private String name;
private int age;
private Date birthday;
// getter/setter 省略
}
public class Test {
public static void main(String[] args) {
User u = new User();
// 批次設值
Map<String, Object> data = Map.of(
"name", "張三",
"age", "25",
"birthday", System.currentTimeMillis()
);
data.forEach((k, v) -> ReflectionUtils.setFieldValue(u, k, v));
// 遍歷輸出
for (FieldInfo fi : ReflectionUtils.getFieldInfos(u)) {
Object val = ReflectionUtils.getFieldValue(u, fi.name);
System.out.printf("%s (%s) = %s%n", fi.name, fi.type.getSimpleName(), val);
}
}
}
MethodHandle / VarHandle (Java 9+)反射是雙面刃:框架開發的利器,業務程式碼的隱患。理解其原理與代價,在正確場景下謹慎使用。