首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java 反射:根據屬性名獲取 Getter 方法,優雅跳過無 Getter 的屬性

     編輯:程式設計疑難解答

需求:給定屬性名(如 `"name"`),獲取對應的 Getter 方法(`getName()`),若屬性無 Getter 則跳過不拋異常。

錯誤做法:直接 getMethod 拋異常


Method getter = clazz.getMethod("get" + capitalize(fieldName));  // 找不到拋 NoSuchMethodException

正確做法:先獲取所有方法再篩選


public static Method findGetter(Class clazz, String fieldName) {
  String getterName = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
  // boolean 型可能是 isXxx()
  String booleanGetter = "is" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
  
  for (Method method : clazz.getMethods()) {  // getMethods 含繼承的 public 方法
    String name = method.getName();
    if ((name.equals(getterName) || name.equals(booleanGetter)) 
        && method.getParameterCount() == 0 
        && method.getReturnType() != void.class) {
      return method;
    }
  }
  return null;  // 無 Getter 返回 null,調用者判斷
}

完整工具類示例


public class ReflectionUtils {
  
  public static Method getGetter(Class clazz, String fieldName) {
    if (clazz == null || fieldName == null) return null;
    
    String cap = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
    String[] candidates = {"get" + cap, "is" + cap};
    
    for (Method m : clazz.getMethods()) {
      if (m.getParameterCount() != 0) continue;
      for (String cand : candidates) {
        if (m.getName().equals(cand) && m.getReturnType() != void.class) {
          return m;
        }
      }
    }
    return null;
  }
  
  // 批量獲取所有可讀屬性的 Getter
  public static Map getAllGetters(Class clazz) {
    Map map = new LinkedHashMap<>();
    for (Method m : clazz.getMethods()) {
      if (m.getParameterCount() == 0 && m.getReturnType() != void.class) {
        String name = m.getName();
        if (name.startsWith("get") && name.length() > 3) {
          String field = Character.toLowerCase(name.charAt(3)) + name.substring(4);
          map.put(field, m);
        } else if (name.startsWith("is") && name.length() > 2) {
          String field = Character.toLowerCase(name.charAt(2)) + name.substring(3);
          map.put(field, m);
        }
      }
    }
    return map;
  }
}

使用示例


Method getter = ReflectionUtils.getGetter(User.class, "name");
if (getter != null) {
  Object value = getter.invoke(userInstance);
  System.out.println("name = " + value);
} else {
  System.out.println("屬性 name 無公共 Getter");
}

要點總結

  • 用 clazz.getMethods() 遍歷而非 getMethod(),避免異常控制流。
  • 兼容 `getXxx()` 和 `isXxx()`(boolean 型慣例)。
  • 檢查無參數、非 void 返回類型,確保是標準 Getter。
  • 返回 `null` 而非拋異常,調用者決定如何處理無 Getter 情況。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved