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

Java 反射獲取對象方法信息完整實戰指南

     編輯:Java 相關知識

核心 API 概覽

類/接口核心方法說明
ClassgetMethods()獲取所有 public 方法(含繼承)
ClassgetDeclaredMethods()獲取本類聲明的所有方法(不含繼承,不限修飾符)
MethodgetName()方法名
MethodgetReturnType()返回值類型 (Class)
MethodgetParameterTypes()參數類型數組 (Class[])
MethodgetModifiers()修飾符位掩碼
ModifiertoString(mod)修飾符轉字符串

完整工具類實現

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ReflectionUtil {
    /** 打印對象所有 public 方法信息 */
    public static void printPublicMethods(Object obj) {
        Class<?> clazz = obj.getClass();
        System.out.println("=== 類名:" + clazz.getName() + " ===");
        
        Method[] methods = clazz.getMethods(); // 包含繼承的 public 方法
        for (Method method : methods) {
            // 修飾符
            String mods = Modifier.toString(method.getModifiers());
            // 返回類型
            String returnType = method.getReturnType().getSimpleName();
            // 方法名
            String name = method.getName();
            // 參數列表
            Class<?>[] paramTypes = method.getParameterTypes();
            StringBuilder params = new StringBuilder();
            for (int i = 0; i < paramTypes.length; i++) {
                if (i > 0) params.append(", ");
                params.append(paramTypes[i].getSimpleName());
                params.append(" arg").append(i);
            }
            
            System.out.printf("%s %s %s(%s)%n", mods, returnType, name, params);
        }
    }
    
    /** 打印對象聲明的所有方法(含 private) */
    public static void printDeclaredMethods(Object obj) {
        Class<?> clazz = obj.getClass();
        System.out.println("=== " + clazz.getSimpleName() + " 聲明的方法 ===");
        
        for (Method method : clazz.getDeclaredMethods()) {
            String mods = Modifier.toString(method.getModifiers());
            String returnType = method.getReturnType().getSimpleName();
            String name = method.getName();
            Class<?>[] params = method.getParameterTypes();
            String paramStr = Arrays.stream(params)
                .map(Class::getSimpleName)
                .collect(Collectors.joining(", "));
            System.out.printf("%s %s %s(%s)%n", mods, returnType, name, paramStr);
        }
    }
}

測試驗證

public class ReflectionDemo {
    public static void main(String[] args) {
        // 測試 String 類
        ReflectionUtil.printPublicMethods("Hello");
        System.out.println();
        
        // 測試自定義類
        ReflectionUtil.printDeclaredMethods(new UserService());
    }
}

class UserService {
    public void save(User user) { }
    private boolean validate(String data) { return true; }
    protected User findById(Long id) { return null; }
    List<User> listAll() { return List.of(); } // package-private
}

class User { private String name; }

輸出示例

=== 類名:java.lang.String ===
public int hashCode()
public boolean equals(Object arg0)
public String toString()
public int compareTo(Object arg0)
... (更多繼承自 Object 的方法)

=== UserService 聲明的方法 ===
public void save(User)
private boolean validate(String)
protected User findById(Long)
List listAll()

進階應用:方法調用

public static Object invokeMethod(Object target, String methodName, Object... args) 
        throws Exception {
    Class<?>[] paramTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new);
    Method method = target.getClass().getDeclaredMethod(methodName, paramTypes);
    method.setAccessible(true); // 破解 private
    return method.invoke(target, args);
}

// 使用
UserService service = new UserService();
invokeMethod(service, "validate", "test-data"); // 調用私有方法

性能與安全提示

  • 緩存 Class/Method 對象:反射調用比直接調用慢 10-100 倍,熱點路徑必須緩存
  • setAccessible(true) 會繞過安全檢查,生產環境慎用,需配置 SecurityManager
  • 優先考慮 MethodHandle (JDK 7+) 或 VarHandle (JDK 9+) 獲得更好性能

總結

反射是框架開發的基石(Spring、Hibernate、Jackson 等)。掌握 Class、Method、Modifier 核心 API,配合緩存策略,可安全高效實現動態代理、插件系統、序列化等高級功能。

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