가자미의 개발이야기
[Java] 자바 와일드카드 본문
a. 와일드카드
위가 제네릭 메소드, 아래가 와일드카드 메소드이다.
기능적으로는 동일하지만 와일드카드가 더 간결하므로 와일드 카드를 선호한다.
제네릭 타입에 다형성을 적용하기 위함.
표현 | 와일드카드 종류 | 설명 |
<?> | 와일드카드 | 제한 없음. 모든 타입 가능 <? extends Object>와 동일 |
<? extends T> | 상한 제한 와일드카드 | T와 그 자손들만 가능 |
<? super T> | 하한 제한 와일드카드 | T와 그 조상들만 가능 |
b. 상한 제한된 와일드카드
제네릭 클래스의 상속과 같이 타입매개변수를 extends로 제한하는 기능이다.
이 경우 box의 타입은 Number Integer Double로 제한된다.
가장 상위 클래스를 제한하는 의미
b-1. 상한 제한의 목적
outBox는 와일드카드 상한제한을 통해 set에 new Toy가 들어가는 오류를 막는다!
왜 막을까?
만약 Toy의 자식인 Car가 매개변수 타입이라고 생각하자. 그렇다면 box의 타입은?
당연히 Car이다.
그런데 box.set(new Toy())?
Car ob=new Toy()가 불가능하다!!!(상속개념)(안전성 상승)
쉽게 Box<? extends Toy> box 대상으로 넣는게 안된다고 이해하자!
c. 하한 제한된 와일드카드
하한 제한은 super로 한다.
extends와 반대로, Integer 와 부모만 올 수 있다.
Integer, Number, Object...
c-1. 하한 제한의 목적
이번엔 하한 제한으로 꺼내는 메소드에서 에러가 걸리고 있다.
d. 제한된 와일드카드와 오버로딩
만약 위의 예제에서 Toy와 아무 관련 없는 Snack클래스가 있다고 가정하자
매개변수로 Box<Snack>을 해당 메소드로 활용하고 싶은데 현재 메소드들은 Box<Toy> 인스턴스를 대상으로 정의된 메소드이다.
이를 오버로딩으로 해결할 수 있을까?
public static void outBox(Box<? extends Toy> box) {}
public static void outBox(Box<? extends Robot> box) {} 이런 형태의 오버로딩은 불가능하다
public static void inBox(Box<? super Toy> box, Toy n) {}
public static void inBox(Box<? super Robot> box, Robot n) {} 얘네는 두번째 매개변수로 인해 오버로딩 인정!
왜? type erasure 때문!! 컴파일러가 밑줄친 부분을 자기가 지운다.
그렇게 되면 위 두 문장은 같은 문장이 되어버려서 오버로딩이 안되는 것!
이런 불편함을 해결하기 위해...
d-1. 와일드카드 선언을 갖는 제네릭 메소드
public static void outBox(Box<? extends Toy> box){}
public static void outBox(Box<? extends Robot> box){} 이 문제의 두 문장을...
public static <T> void outBox(Box<? extends T> box){}
outBox는 Box<T>를 인자로 받고 꺼내는거만 가능하다는 거구나!(? extends)
'Java > 자바 기본 문법' 카테고리의 다른 글
자바 컬렉션 프레임워크 Set<E> : HashSet, TreeSet (0) | 2021.02.02 |
---|---|
자바 컬렉션 프레임워크-List<E> : ArrayList, LinkedList, Stack, Queue (0) | 2021.02.02 |
[Java] 자바 제네릭의 상속과 타겟타입 (0) | 2021.01.22 |
[Java] 제네릭 (0) | 2021.01.21 |
자바 Arrays 클래스 (0) | 2021.01.20 |