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 |