enum Operator {
    ADD('+'), SUBTRACT('-'), MULTIPLY('*'), DIVIDE('/'), MODULUS('%');

    char operator;

    Operator(char operator) {
        this.operator = operator;
    }

    public char getOperator(){
        return operator;
    }

    public static Operator getOperatorEnum(char operator){
        for(Operator op : values()) {
            if(op.getOperator() == operator){
                return op;
            }
        }
        return null;
    }
}

 

1. getOperator()는 static이 아닌데, 왜 getOperatorEnum()에서 호출 가능할까?

 

static 메서드는 클래스 자체에 속한 메서드 (객체 생성 없이 사용 가능)

인스턴스 메서드는 객체에 속한 메서드 (객체를 생성해야 사용 가능)

Operator[] ops = Operator.values(); // [ADD, SUBTRACT, MULTIPLY, DIVIDE, MODULUS]
  • values() 메서드는 enum의 모든 상수(객체)를 배열로 반환하는 정적 메서드
  • enum을 선언하면, 컴파일러가 자동으로 values() 메서드를 추가
  • for-each문의 op 자체가 Operator의 인스턴스(객체)
  • static이 아니어도 객체를 통해 호출하면 문제없음

=> 정적 메서드 `getOperatorEnum()`가 인스턴스 메서드(동적 메서드) `getOperator()`에 접근 가능!

 


 

2. Operator 반환 타입인데 null을 반환해도 되는 이유?

 

null은 객체가 아직 할당되지 않았다는 의미로 모든 참조 타입(객체)에 사용 가능

Operator도 결국 객체 타입이기 때문에 null을 반환할 수 있다.

 

번외) throw가 가능한 이유

public static Operator getOperatorEnum(char operator) {
    for (Operator op : values()) {
        if (op.getOperator() == operator) {
            return op;
        }
    }
    throw new IllegalArgumentException("Invalid operator: " + operator);
}

 

예외가 발생하면 메서드 실행이 중단되고, 예외가 호출한 곳으로 전달됨

=> 프로그램이 강제 종료되기 때문에, 반환값이 없어도 상관이 없는 것!

 


 

 

3. 클래스의 제네릭 타입을 보면 Number 추상 클래스를 상속받고 있는데, 왜 Number의 추상 메서드를 구현 안해도 문제가 일어나지 않을까?

public class Calculator<T extends Number, E extends Number> {}

public class Calculator extends Number {}

 

두 번째 코드의 경우는 Number의 추상 메서드를 구현해야 한다.

첫 번째 코드의 경우는 Calculator 클래스가 실제로 Number 클래스를 상속받는 게 아니라, Number 클래스 하위에 있는 클래스가 타입 매개변수임을 명시하기 위한 코드이다.

=> 실제로 상속받는 코드가 아니므로 추상 메서드 구현 의무 없음!