public Object getOrderby() {
if (ORDER_TITLE.equals(ordered)) return getTitle();
else if (ORDER_RENDERDATE.equals(ordered)) return getRenderDate();
else if (ORDER_CREATEDATE.equals(ordered)) return getCreateDate();
else if (ORDER_LASTMODIFIED.equals(ordered)) return getLastModified();
else return getTitle(); // 新增欄位必須修改此方法 → 違反開放封閉原則
}
private Object doGetMethod(String methodName) throws Exception {
String getterName = "get" + methodName.substring(0,1).toLowerCase() + methodName.substring(1);
// 或簡化:getterName = "get" + methodName.toLowerCase(); // 視命名規範而定
for (Method method : getClass().getMethods()) {
if (getterName.equalsIgnoreCase(method.getName())) {
return method.invoke(this); // 無參數調用
}
}
return null; // 或拋出異常
}
public Object getOrderby() {
Object defaultVal = getTitle();
try {
return doGetMethod(getOrdered()); // 動態調用對應 getter
} catch (Exception e) {
return defaultVal; // 異常回退預設值
}
}
getClass().getMethods():獲取**公開**方法(含繼承),返回 Method[]。method.invoke(this):在當前實例上調用方法,無參數傳空陣列 new Object[0]。equalsIgnoreCase:忽略大小寫匹配,兼容 getTitle/gettitle 等寫法差異。IllegalAccessException、InvocationTargetException 等反射異常。| 方案 | 效能 | 適用場景 |
|---|---|---|
| 反射 + 循環查找 | 較慢 (微秒級) | 低頻調用、配置驅動、插件系統 |
| 反射 + 快取 Map<String, Method> | 接近原生 | 高頻調用、框架開發 |
| MethodHandle (Java 7+) | 最快 | 極高效能要求、動態語言支援 |
| Lambda/方法引用 Map | 原生速度 | 現代 Java、固定方法集合 |
private static final Map GETTER_CACHE = new ConcurrentHashMap<>();
private Object doGetMethodCached(String methodName) throws Exception {
String getter = "get" + Character.toLowerCase(methodName.charAt(0)) + methodName.substring(1);
Method method = GETTER_CACHE.computeIfAbsent(getter, key -> {
try { return getClass().getMethod(key); }
catch (NoSuchMethodException e) { return null; }
});
return (method != null) ? method.invoke(this) : null;
}
// Java 8+:方法引用 Map,零反射、類型安全、極速
private static final Map> GETTERS = Map.of(
"title", MyClass::getTitle,
"renderDate", MyClass::getRenderDate,
"createDate", MyClass::getCreateDate,
"lastModified", MyClass::getLastModified
);
public Object getOrderby() {
return GETTERS.getOrDefault(getOrdered(), this::getTitle).get();
}
反射動態調用 Getter 是解決「硬編碼 if-else 鏈」的經典技巧,**核心價值在於開放封閉原則的落地**:新增欄位只需新增方法並註冊映射,**零修改既有邏輯**。現代 Java 建議優先使用 Map<String, Supplier> 或 MethodHandle,兼顧效能、類型安全與可維護性。