enum 클래스의 자동생성되는 것들
1. values()
메서드
- 자동 생성:
values()
메서드는 모든enum
클래스에서 자동으로 생성됩니다. 이 메서드는enum
의 모든 상수를 배열로 반환합니다. - 사용 예:
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}
public class Main {
public static void main(String[] args) {
// values() 메서드를 사용하여 enum의 모든 상수를 가져옵니다.
Day[] days = Day.values();
for (Day day : days) {
System.out.println(day);
}
}
}
- 출력:
MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY
2. valueOf(String name)
메서드
- 자동 생성:
valueOf(String name)
메서드도 자동으로 생성됩니다. 이 메서드는enum
의 이름을 기반으로 특정enum
상수를 반환합니다. - 사용 예:
Day day = Day.valueOf("MONDAY");
System.out.println(day); // MONDAY
3. 생성자
- 자동 생성:
enum
클래스는 일반 클래스와 달리 생성자가 자동으로 제공됩니다.enum
생성자는 암묵적으로private
이며, 외부에서 인스턴스를 생성할 수 없습니다. - 사용 예:
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
private Day() {
System.out.println(this + " 생성자 호출");
}
}
public class Main {
public static void main(String[] args) {
Day day = Day.MONDAY; // 여기서 생성자가 호출됩니다.
}
}
- 출력:
MONDAY 생성자 호출 TUESDAY 생성자 호출 WEDNESDAY 생성자 호출 THURSDAY 생성자 호출 FRIDAY 생성자 호출 SATURDAY 생성자 호출 SUNDAY 생성자 호출
Java에서 enum은 클래스로 정의되며, 각 enum 상수는 해당 enum 클래스의 인스턴스입니다. enum 클래스가 로드될 때, JVM은 해당 클래스의 모든 상수를 미리 생성합니다. 즉, enum 클래스가 처음 사용될 때 (예: Day.MONDAY를 참조할 때), JVM은 enum의 모든 상수들을 인스턴스화합니다.
이 때문에 Day.MONDAY를 참조할 때 Day 클래스의 모든 상수(MONDAY, TUESDAY, WEDNESDAY, etc.)에 대한 생성자가 호출됩니다. 그래서 Day.MONDAY를 한 번 참조했지만, 다른 상수들에 대한 생성자도 모두 호출된 것입니다.
4. ordinal()
메서드
- 자동 생성:
ordinal()
메서드는 해당enum
상수의 순서를 반환합니다. 첫 번째 상수의 순서는 0입니다. - 사용 예:
int index = Day.MONDAY.ordinal();
System.out.println(index); // 0
요약
- 자동 생성되는 메서드:
values()
: 모든enum
상수를 배열로 반환합니다.valueOf(String name)
: 이름으로enum
상수를 반환합니다.ordinal()
:enum
상수의 순서를 반환합니다.
- 자동 생성되는 생성자:
enum
생성자는 자동으로 제공되며private
입니다. 외부에서 인스턴스를 생성할 수 없습니다.
이처럼 enum
클래스에는 자동으로 제공되는 메서드와 생성자가 있어서 별도로 구현하지 않아도 기본적인 기능을 사용할 수 있습니다.
InvocationHandler
InvocationHandler는 자바의 리플렉션 API에서 동적 프록시(Dynamic Proxy)를 구현할 때 사용되는 인터페이스입니다InvocationHandler를 사용하면 메서드 호출을 가로채고, 해당 메서드가 어떻게 동작할지 동적으로 결정할 수 있습니다. 동적 프록시는 런타임에 생성되며, 인터페이스를 구현하는 클래스를 대신하여 동작할 수 있습니다.
CalculatorService 인터페이스 정의
// 간단한 계산기 서비스 인터페이스
public interface CalculatorService {
int add(int a, int b);
int subtract(int a, int b);
}
CalculatorServiceImpl 클래스 정의 ( CalculatorService 인터페이스 구현 )
// CalculatorService 인터페이스를 구현한 실제 서비스 클래스
public class CalculatorServiceImpl implements CalculatorService {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int subtract(int a, int b) {
return a - b;
}
}
InvocationHandler 구현
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
// InvocationHandler 구현체, 여기서 CalculatorService의 메서드 호출을 가로챕니다.
public class CalculatorInvocationHandler implements InvocationHandler {
private CalculatorService target; // 실제 메서드를 호출할 CalculatorService 객체
public CalculatorInvocationHandler(CalculatorService target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 메서드 호출 전에 로그를 남깁니다.
System.out.println("메서드 " + method.getName() + " 호출 중입니다. 매개변수: " + args[0] + ", " + args[1]);
// 실제 객체의 메서드를 호출합니다.
Object result = method.invoke(target, args);
// 메서드 호출 후 결과를 로그에 남깁니다.
System.out.println("메서드 " + method.getName() + " 호출이 끝났습니다. 결과: " + result);
return result;
}
}
프록시 생성 및 사용
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
// 실제 서비스 객체 생성
CalculatorService calculatorService = new CalculatorServiceImpl();
// InvocationHandler 구현체를 통해 프록시 생성
CalculatorService proxyInstance = (CalculatorService) Proxy.newProxyInstance(
calculatorService.getClass().getClassLoader(),
calculatorService.getClass().getInterfaces(),
new CalculatorInvocationHandler(calculatorService)
);
// 프록시 객체를 통해 메서드를 호출
int addResult = proxyInstance.add(5, 3);
int subtractResult = proxyInstance.subtract(10, 7);
}
}
메서드 add 호출 중입니다. 매개변수: 5, 3
메서드 add 호출이 끝났습니다. 결과: 8
메서드 subtract 호출 중입니다. 매개변수: 10, 7
메서드 subtract 호출이 끝났습니다. 결과: 3
'Everyday Study' 카테고리의 다른 글
2024.08.23(금) { AOP Alliance, 외워야할 정보 } (0) | 2024.08.23 |
---|---|
2024.08.22(목) { Qualified Name, @DirtiesContext, 체이닝 메서드, MOCK } (0) | 2024.08.22 |
2024.08.20(화) { 클래스 로더, .invoke, seald, qualified name } (0) | 2024.08.20 |
2024.08.19(월) { 타겟 클래스, Stream } (0) | 2024.08.20 |
2024.08.16(금) { 와일드카드 캡쳐, transient } (0) | 2024.08.16 |