https://www.youtube.com/watch?v=n28M8iryFPw
제네릭의 정의
다양한 타입의 객체들을 다루는 메서드나 클래스에
컴파일 시의 타입 체크를 해주는 기능
컴파일이란
사람이 이해하는 단어를 컴퓨터가 이해할 수 있는 언어로 바꿔주는 과정
컴파일의 효과
객체의 타입 안정성을 높이고, 형변환의 번거로움이 줄어든다
public class Box<T> { }
T = 타입 매개변수
Box<T> = 제네릭 클래스
public class Box<T> {
List<T> items = New ArrayList<>();
public void add(T item) {
items.add(item);
}
}
Box<T> 제네릭 클래스를 만들어보았다
public static void main(String[]args) {
Box<String> box = new Box<String>();
}
제네릭클래스에 타입매개변수로 String을 만들어 보낸다면
public class Box<String> {
List<String> items = New ArrayList<>();
public void add(String item) {
items.add(item);
}
}
T 부분이 String으로 자동으로 형변환 되어 사용된다
제네릭을 쓰면 뭐가 좋은가!
- 강력한 타입 체크를 해준다
- 형변환을 하지 않아도 된다
제네릭 사용법
참조변수와 생성자에 대입된 타입이 일치해야한다!
Box<Apple> appleBox = new Box<Apple>(); O
Box<Grape> grapeBox = new Box<Grape>(); O
Box<Fruit> FruitBox = new Box<Apple>(); X
// Apple 이 Fruit를 상속해도 불가능!!
제네릭 클래스가 상속관계인 것은 괜찮다
Box<Fruit> fruitBox = new FruitBox<Fruit>(); O
// Box를 상속받는 클래스인 FruitBox 가능!
List<Fruit> fruitBox = new ArrayList<Fruit>(); O
// List를 상속받는 클래스인 ArrayList 가능!
Box<Fruit> grapeBox = new FruitBox<Apple>(); X
// 단, 여전히 대입되는 타입은 같아야함!!
제한된 제네릭
public class Box<T extends Fruit> {
List<T> items = New ArrayList<>();
public void add(T item) {
items.add(item);
}
}
T는 어떤 타입이든 들어올 수 있지만
Fruit를 상속받은 타입만 들어올 수 있는 것!
타입 매개변수를 이렇게 표기하는 것은 '관례'이다
- T - Type
- E - Element (요소)
- K - Key
- V - Value
- N - Number
- S, U, V .. - 2nd, 3rd, 4th types...
(타입을 잇는 두번째타입, 세번째타입)
제네릭 메서드
public <T> T foo(List<T> list) { }
<T> = 타입 매개변수
T = 리턴 타입
foo = 메소드명
List<T> list = 매개변수
일반 메서드와 다른점은 리턴타입 앞에 타입 매개변수를 사용한다는 점
만약 전달되는 타입 매개변수의 범위를 제한하고 싶다면?
타입매개변수 위치에 extends 를 해주면 된다!
public <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
와일드 카드는 ' ? ' 기호로 표현하고
와일드 카드는 어떠한 타입도 될 수 있다
public static void print List(List<Object> list) {
for (Object elem : list) {
System.out.println(elem + " ");
}
}
public static void main(String[]args){
List<Fruit> fruits = new ArrayList<>();
MyClass.printList( fruits ); // 에러
}
에러가 나타나는 이유는 제네릭에 Object를 넣어놔서
Object형의 요소를 갖는 List만 들어올 수 있기 때문이다
public static void print List(List<? extends Object> list) {
for (Object elem : list) {
System.out.println(elem + " ");
}
}
와일드 카드를 사용하여 모든 타입이 들어올 수 있도록 수정
< ? extends Object > 를 통해 와일드 카드를 사용할 수 있다
'경험 및 후기' 카테고리의 다른 글
(영상후기) 정규표현식 (0) | 2022.07.22 |
---|---|
[영상후기] OOP 객체지향 프로그래밍 (0) | 2022.07.11 |
[영상후기] MVC 패턴 (0) | 2022.07.09 |
[영상후기] 도서관리 시스템 (AWS) (0) | 2022.07.09 |
(오답노트) 상속, 컬렉션 프레임워크 오답 (0) | 2022.06.27 |