본문 바로가기

개발자노트/우아한 테코톡 감상

[10분 테코톡] 두강의 Generics ( 제네릭 )

Generics [ 타입 문지기 ]

정의 : 다양한 타입의 객체들을 다루는 메서드나 클래스에 컴파일 시의 타입 체크를 해주는 기능
- 의도하지 않은 타입이 들어오는 것을 막는다.(타입체크)
효과 : 객체의 타입안전성을 높이고, 형변환의 번거로움이 줄어든다.

public class Box<String> {}
         String: 타입 매개변수
   Box<String> : 제네릭 클래스


제네릭을 쓰면 무엇이 좋은가?

1. 강력한 타입 체크를 해준다.
2. 형변환을 하지 않아도 된다.

제네릭 사용법
✔ 참조변수와 생성자에 대입된 타입이 일치해야한다.
Box<Apple> appleBox = new Box<Apple>(); 가능
Box<Fruit> fruitBox = new Box<Apple>(); 불가능
=상속관계여도 대입된 타입이 일치하지 않으면 사용 불가.

✔ 제네릭 클래스가 상속 관계인 것은 괜찮다
Box<Fruit> fruitBox = new FruitBox<Fruit>(); 가능
Box<Fruit> fruitBox = new AppleBox<Apple>(); 불가능


제한된 제네릭
public class Box<T extends Fruit>(); -> 어떤 타입이든 들어올 수 있지만 Fruit을 상속해야만 들어올 수 있다.


다양한 타입 매개변수
T- Type 
E - Element (요소)
K - Key (웹에서 주로 사용)
V - Value (웹에서 주로 사용)
N - Number
S,U,V .. - 2nd,3rd,4th types...

타입 매개변수를 이렇게 표기하는 것이 관례이다.
하지만, 원한다면 자신이 원하는 대로 표기하여 사용해도 문제가 되진 않는다.

 

제네릭 메서드
public <T> foo(List<T> list) {}
<T> : 타입 매개변수
T : 리턴 타입
foo : 메소드명
List<T> list : 매개변수

만약, 전달되는 타입 매개변수의 범위를 제한하고 싶다면?
public <T> T foo(List<T extends Fruit> list) {} // X
public <T extends Fruit> T foo(List<T> list) {} // O
뒤에있는 매개변수쪽에서 범위를 제한하는 것이 아니라,
앞에있는 전달받는 타입매개변수 쪽에서 범위를 제한해줘야함.

제네릭 메서드의 사용


Box box = new Box<>();
box.printParamClass("String");
box.printParamClass(1);
box.printParamClass(3.14);

=> 사용 가능~!


- 제네릭 메서드는 제네릭 클래스가 아닌 일반 클래스에서도 사용 가능하다.
public class MyClass {
public <T> void printParamClass(T t) {
Syso(t.getClass());
}
}


와일드카드
- 와일드카드는 '?' 기호로 표현하고,
와일드 카드는 어떠한 타입도 될 수 있다.

- 아무 타입의 list를 출력하는 메서드
Object를 사용하지 못하는 이유: 정확히 Object형의 요소를 갖는 List만 들어 올 수 있기 때문에.
-> 그래서, 뒤에 있는 매개변수에 ? extends Object를 해줘야함
    public static void printList(List<? extends Object> list)


결론
- 제네릭은 형변환의 번거로움을 줄이고,
- 의도하지 않은 타입이 들어오는 것을 막기 위한 것 ( 강력한 타입 체크 )

 

 

 

자료 : https://www.youtube.com/watch?v=n28M8iryFPw