Java - wildcard

eden6187·2021년 7월 4일
0

Java

목록 보기
2/4
post-thumbnail

Wildcard란?

Bounded Wildcard

upper bounded wild card의 문법적 의미

Box<? extends Number> box

위의 와일드 카드 선언은

"Box class의 type parameter를 Number와 Number의 하위 타입으로 제한한다."는 문법적 의미
를 지닌다.

upper bounded wild card는 언제 사용해야 할까?

Box<? extends Number> box

결론부터 말하자면 box가 참조하는 대상으로 꺼내는 작업만 허용하겠다는 의미이다.

즉, box의 method중 parameter에 Type parameter(ex. T)가 정의 되어 있는 경우 그 method들을 사용하지 못하게 제한하겠다는 의미이다.

그렇다면 왜 "? extends Number"라는 선언이 이러한 암시적인 의미를 지니게 되는 것일까?

이는 문법적 의미를 생각해 보면 알 수 있다.

만약 Box 클래스가 다음과 같이 이루어져 있다면

class Box<T> {
    private T content;
    public void setContent(T content){ this.content = content } // Box Method-(1)
    public T changeToy(T newToy){ // Box Method-(2)
        T oldToy = this.content;
        this.content = newToy;
        return oldToy;
    }
    public T getContent(){ return this.content } // Box Method-(3)
}

다음과 같은 제네릭 메소드를 사용 할 때

public static void unBox(Box<? extends Toy> box){
	box.setContent(new Toy()); // Generic Method-(1)
}

(1)과 같이 box에 실수로 값을 넣으려 할 경우 컴파일 에러가 발생하게 된다.

이렇게 되는 이유는 box의 type 변수가 Toy를 상속하는 것은 맞지만 구체적으로 어떠한 type인지는 알 수 없기 때문이다.

public static void unBox(Box<? extends Toy> box){
	Toy content = box.getContent(); // Generic Method-(2)
}

반면, (2)와 같이 box에서 값을 가져오고자 할 경우에는 구체적인 type을 알 수는 없지만 box에서 나올 type은 Toy의 subtype이기 때문에 정상적으로 수행이 가능하다.

좀 더 확장해서 생각해 본다면 Box Method-(1) 또는 (2)의 경우 type parameter(T)를 method의 parameter로 가지고 있다.

이러한 method를 사용하게 될 경우 Box Method-(1),(2)의 paramter로 사용 될 수 있는 값들은 type 자체를 확정 할 수 없기 때문에 애초에 함수를 호출 하는 것이 불가능 하다.

한가지 확실 하게 알 수 있는 것은 Box Method-(3)과 같이 type parameter를 method의 반환 값으로 사용 할 경우 그 값은 반드시 Toy의 subtype이라는 것이다.

lower bounded wild card의 문법적 의미

lower bounded wild card 예시

Box<? super Number> box

"Box class의 type parameter를 Number와 Number의 상위 타입으로 제한한다."는 문법적 의미를 지닌다.

lower bounded wild card는 언제 사용해야 할까?

Box<? super Number> box

결론부터 말하자면 box가 참조하는 대상으로 넣는 작업만 허용하겠다는 의미이다.

즉, box의 method중 반환값에 Type parameter(ex. T)가 정의 되어 있는 경우 그 method들을 사용하지 못하게 제한하겠다는 의미이다.

그렇다면 왜 "? super Number"라는 선언이 이러한 암시적인 의미를 지니게 되는 것일까?

이는 문법적 의미를 생각해 보면 알 수 있다.

다음과 같은 제네릭 메소드를 사용 할 때

public static void box(Box<? super Toy> box){
	Toy toy = box.getContent(); // Generic Method-(3)
}

Generic Method-(3)과 같이 box에 실수로 값을 넣으려 할 경우 컴파일 에러가 발생하게 된다.

이렇게 되는 이유는 box의 type 변수가 Toy의 상위 type인 것은 맞지만 구체적으로 어떠한 type인지는 알 수 없기 때문이다.

public static void box(Box<? super Toy> box){
	box.setContent(new Toy()); // Generic Method-(4)
}

반면, (4)와 같이 box에 값을 넣고자 할 경우에는 구체적인 type을 알 수는 없지만 box가 가진 type이 Toy의 상위 클래스인 것은 확실히 알 수 있기 때문에 컴파일 에러가 발생하지 않는다.

좀 더 확장해서 생각해 본다면 Box Method-(1) 또는 (2)의 경우 type parameter(T)를 method의 parameter로 가지고 있다.

Box Method-(3)과 같이 type parameter를 method의 반환 값으로 사용 할 경우 그 값이 구체적으로 어떠한 Type인지 알 수 없다. 알 수 있는 정보라고는 Object를 상속하는 type이라는 정보 뿐이다.

반면, 한가지 확실 하게 알 수 있는 것은 Box Method-(1),(2)의 paramter로 사용 될 수 있는 값들은 type이 항상 Toy의 상위 클래스이기 때문에 Toy를 항상 정상적으로 받을 수 있다는 것이다.

결론

Box<? extends Number> box

절대 모르는 것 : box가 참조하고 있느 Box 객체의 Method의 parameter의 Type
확실하게 알 수 있는 것 : box가 참조하고 있는 Box 객체의 Method의 반환형

Box<? super Number> box

절대 모르는 것 : box가 참조하고 있는 Box 객체의 Method의 반환형
확실하게 알 수 있는 것 : box가 참조하고 있느 Box 객체의 Method의 parameter는 항상 Number의 상위 Type이다.

출처

윤성우의 열혈 Java Programming

0개의 댓글

관련 채용 정보