首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 反射實現動態 Getter 調用:消除硬編碼 if-else 鏈

     編輯:Java 相關知識

痛點代碼


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(); // 新增欄位必須修改此方法 → 違反開放封閉原則
}

反射重構方案

1. 通用動態調用方法


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; // 或拋出異常
}

2. 簡化業務邏輯


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,兼顧效能、類型安全與可維護性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved