反射雖強大但 API 繁瑣,ReflectUtils 封裝了構造器實例化、屬性獲取/設置(支持巢狀屬性)、方法調用、暴力反射讀寫私有字段、兩個 Bean 差異比較等高頻操作,可直接納入項目公共庫。
| 方法 | 用途 | 關鍵點 |
|---|---|---|
constructorNewInstance | 指定構造器參數類型/值創建實例 | setAccessible(true) 破壞私有構造器 |
getProperty / setProperties | 標準 JavaBean 屬性讀寫 | 基於 PropertyDescriptor,支持 getter/setter |
getBeanInfoProperty / setBeanInfoProperty | Commons BeanUtils 風格,字符串值,支持巢狀路徑 | user.address.city 形式 |
getPropertyUtilByName / setPropertyUtilByName | Commons PropertyUtils,保持原始類型 | 區別於 BeanUtils 的字符串轉換 |
methodInvoke | 指定類/方法/參數類型/值調用方法 | 支持私有方法 |
compareBeanValue | 比較兩個 Bean 差異,返回變更描述字符串 | 配合字段註釋 Map,適合審計日誌 |
getFieldValue / setFieldValue | 暴力反射讀寫任意字段(含私有、繼承鏈) | Apache Commons Lang FieldUtils |
public static Field getTargetField(Class> targetClass, String fieldName) {
if (targetClass == null || Object.class.equals(targetClass)) return null;
Field field = FieldUtils.getDeclaredField(targetClass, fieldName, true); // 含私有
if (field == null) {
return getTargetField(targetClass.getSuperclass(), fieldName); // 遞歸向上
}
return field;
}
public staticString compareBeanValue(Map fields, T oldBean, T newBean) { StringBuilder sb = new StringBuilder(); for (Map.Entry e : fields.entrySet()) { String prop = e.getKey().toLowerCase(); Object oldVal = getProperty(prop, oldBean); Object newVal = getProperty(prop, newBean); if (Objects.equals(oldVal, newVal)) continue; sb.append("字段注釋: ").append(e.getValue()) .append("】原屬性值\"").append(emptyToSpace(oldVal)) .append("\"現屬性值\"").append(emptyToSpace(newVal)).append("\";"); } return sb.toString(); }
org.apache.commons:commons-lang3(FieldUtils、StringUtils)。org.apache.commons:commons-beanutils(BeanUtils、PropertyUtils)。生產環境建議:
1. 緩存PropertyDescriptor/Method/Field避免重複反射開銷。
2. 異常統一拋RuntimeException或自定義檢查異常,調用者決策處理。
3. 大量反射場景考慮字節碼生成庫(ByteBuddy、ASM)替代,性能提升 10-100 倍。