본문 바로가기

Java

Method Class

Method Class

자바의 Method 클래스는 java.lang.reflect 패키지에 속해 있으며, 개별 클래스의 메소드를 나타냅니다. 이 클래스를 사용하면 리플렉션(reflection)을 통해 클래스의 메타데이터를 조사하고, 런타임에 동적으로 메소드를 호출할 수 있습니다.
[https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html ]

Method 객체는 다음과 같은 주요 기능을 제공합니다:
1. 메소드 정보 조회: 메소드 이름, 리턴 타입, 파라미터 타입, 접근 제한자 (public, private 등)와 같은 정보를 얻을 수 있습니다.
2. 메소드 실행: invoke 메소드를 사용해 특정 객체에 대한 메소드 호출을 동적으로 실행할 수 있습니다. 이 때, 필요한 인자를 invoke 메소드의 파라미터로 전달합니다.
3. 어노테이션 처리: 메소드에 적용된 어노테이션을 조회하거나 처리할 수 있습니다.
4. 타입 정보 접근: 제네릭 타입 정보를 포함한 메소드의 파라미터와 반환 타입에 대한 정보를 얻을 수 있습니다.

Method 객체는 보통 Class 객체의 getMethod나 getDeclaredMethods 메소드를 사용하여 얻습니다.
이러한 리플렉션 기능은 자바의 다이내믹한 특성을 활용할 때 매우 유용하지만, 성능 저하의 원인이 될 수 있으므로 필요한 경우에만 사용하는 것이 좋습니다.

Method 클래스의 주요 메소드와 기능은 다음과 같습니다.
1. 메소드 이름과 반환 타입:
   • getName(): 메소드의 이름을 반환합니다.
   • getReturnType(): 메소드의 반환 타입을 Class 객체로 반환합니다.
2. 파라미터 정보:
   • getParameterTypes(): 메소드의 파라미터 타입을 Class 객체 배열로 반환합니다.
   • getParameterCount(): 메소드의 파라미터 개수를 반환합니다.
3. 메소드 호출:
   • invoke(Object obj, Object... args): 주어진 객체에 대해 이 메소드를 지정된 인자로 실행합니다.

     첫 번째 인자는 메소드가 실행될 객체이며, 나머지 인자는 메소드 호출 시 사용될 파라미터입니다.
4. 접근 제어자 및 수정자 정보:
   • getModifiers(): 메소드의 접근 제어자와 수정자를 나타내는 정수를 반환합니다.
5. 어노테이션 정보:
   • getAnnotations(): 메소드에 적용된 모든 어노테이션을 반환합니다.
   • getDeclaredAnnotations(): 직접 선언된 모든 어노테이션을 반환합니다.
6. 예외 타입:
   • getExceptionTypes(): 메소드가 선언하는 예외 타입을 Class 객체 배열로 반환합니다.

Method 클래스는 자바의 리플렉션 API의 핵심적인 부분이며, 메소드의 메타데이터에 접근하거나 메소드를 동적으로 실행하는 데 사용됩니다. 이러한 기능은 프레임워크 개발, 유틸리티 라이브러리, 동적 프록시 생성 등 다양한 상황에서 유용하게 사용됩니다.

public class User {
	String id;
	String name;
	String password;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}
import java.lang.reflect.Method;

public class ReflectionExample {
    public static void main(String[] args) {
        try {
            // User 객체 생성
            User user = new User();

            // User 클래스의 Class 객체 가져오기
            Class<?> clazz = user.getClass();
            
            Method[] methods = clazz.getDeclaredMethods();            

            for (Method method : methods) {
            	System.out.println("method name: " + method.getName());
            	
            	Class<?>[] parameterTypes = method.getParameterTypes();
            	for (Object obj: parameterTypes) {
            		System.out.println("para type: " + obj.toString());
            	}            	        	
            }
            
            // setName 메소드의 Method 객체 가져오기
            Method setNameMethod = clazz.getMethod("setName", String.class);
            setNameMethod.invoke(user, "sung");

            // getName 메소드의 Method 객체 가져오기
            Method getNameMethod = clazz.getMethod("getName");

            // Method 객체를 사용하여 메소드 호출
            String name = (String) getNameMethod.invoke(user);

            // 결과 출력
            System.out.println("Name: " + name);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


아래 예시 코드는 Method 클래스를 사용하여 클래스의 모든 메소드를 나열하고,
특정 조건을 만족하는 메소드만을 호출하는 예제를 만들겠습니다. 이 예제에서는 모든 public 메소드를 찾고, 이 중 메소드 이름이 특정 문자열로 시작하는 메소드만을 호출합니다.

먼저, 리플렉션을 사용할 샘플 클래스를 만듭니다. 예를 들어, Calculator 클래스에 두 개의 메소드가 있다고 가정해 보겠습니다:

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }

    public int multiply(int a, int b) {
        return a * b;
    }
}

 

public class ReflectionExample {
    public static void main(String[] args) {
        try {
            // Calculator 객체 생성
            Calculator calculator = new Calculator();

            // Calculator 클래스의 Class 객체 가져오기
            Class<?> clazz = calculator.getClass();

            // 모든 메소드 가져오기
            Method[] methods = clazz.getDeclaredMethods();

            for (Method method : methods) {
                // 메소드의 파라미터 타입 가져오기
                Class<?>[] parameterTypes = method.getParameterTypes();

                // 아래 코드는 에러가 발생합니다. 단지 참고사항일뿐!!!
                // 임시 파라미터 배열 생성 (예시 값으로 모두 2를 사용)
                Object[] parameters = new Object[parameterTypes.length];
                Arrays.fill(parameters, 2);

                // 메소드 호출
                Object result = method.invoke(calculator, parameters);

                // 결과 출력
                System.out.println("Result of " + method.getName() + ": " + result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


이 코드에서는 다음 단계를 거칩니다:
1. Calculator 객체를 생성합니다.
2. getClass 메소드를 사용하여 Calculator 객체의 Class 객체를 가져옵니다.
3. Class 객체의 getDeclaredMethods 메소드를 사용하여 모든 메소드를 가져옵니다.
4. 각 메소드에 대해, 메소드의 파라미터 타입에 맞춰 적절한 파라미터 값(여기서는 예시로 모두 2)을 제공하고, invoke 메소드를 사용하여 메소드를 실행합니다.

이 예제는 클래스의 모든 메소드를 반복적으로 호출하는 방법을 보여줍니다. 실제 사용 시에는 각 메소드의 파라미터 타입과 개수에 맞는 적절한 파라미터 값을 제공해야 합니다.

다음 코드는 add로 시작하는 특정 메소드를 호출하는 예제 코드를 작성합니다:

import java.lang.reflect.Method;

public class ReflectionExample {
    public static void main(String[] args) {
        try {
            // Calculator 객체 생성
            Calculator calculator = new Calculator();

            // Calculator 클래스의 Class 객체 가져오기
            Class<?> clazz = calculator.getClass();

            // 모든 public 메소드 가져오기
            Method[] methods = clazz.getMethods();

            for (Method method : methods) {
                // 메소드 이름이 "add"로 시작하는 경우에만 메소드 호출
                if (method.getName().startsWith("add")) {
                    // 예시 파라미터 값으로 메소드 호출 (예: add(5, 3))
                    int result = (int) method.invoke(calculator, 5, 3);

                    // 결과 출력
                    System.out.println("Result of " + method.getName() + ": " + result);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


이 코드에서는 다음 단계를 거칩니다:
1. Calculator 객체를 생성합니다.
2. getClass 메소드를 사용하여 Calculator 객체의 Class 객체를 가져옵니다.
3. Class 객체의 getMethods 메소드를 사용하여 모든 public 메소드를 가져옵니다.
4. 반복문을 사용하여 각 메소드에 대해, 이름이 “add”로 시작하는 경우 해당 메소드를 동적으로 호출합니다.

이 예제는 Method 클래스를 사용하여 클래스의 모든 public 메소드를 탐색하고, 특정 조건을 만족하는 메소드를 동적으로 호출하는 방법을 보여줍니다.

'Java' 카테고리의 다른 글

Anonymous Class  (0) 2024.04.08
Nested Classes(중첩 클래스)  (0) 2024.04.08
Java Collection Framework  (0) 2024.04.08
Lambda Expressions  (0) 2024.04.08
Java Advanced Programming Quiz  (0) 2024.04.08