728x90
- 제네릭의 효용
- 중복되거나 필요없는 코드를 줄여줌
- 그러면서도 타입 안정성을 해치지 않음
자바에서는 똑같은 로직을 수행하는 함수를 타입을 지정해야 한다는 이유로 여러번 구현해야 함
-> Object를 사용? 이 경우 타입 안정성을 침해받게 됨
-> 단항 연산자를 사용 x. 두 객체의 타입이 다르다면? 로직과 다른 순서의 타입들이 들어오게 된다면? 등등
- 제네릭 문법 예시로 살펴보기
// 1. 2.
public class Generic<T> {
// 3.
private T t;
public T get() {
return this.t;
}
public void set(T t) {
this.t = t;
}
public static void main(String[] args) {
// 4.
Generic<String> stringGeneric = new Generic<>();
// 5.
stringGeneric.set("Hello World");
String tValueTurnOutWithString = stringGeneric.get();
System.out.println(tValueTurnOutWithString);
}
}
- 제네릭은 클래스 또는 메서드에 사용
- 클래스 이름 뒤 <>에 타입 변수를 지정
- T인 이유는 일종의 컨벤션이기 때문. 그 외 U, V, E 등
- 클래스 내에서 특정 타입에 들어갈 자리에 T가 대신 들어갈 수 있음
- 타입을 String으로 지정한 객체 생성
- 제네릭으로 구현한 클래스 내부의 메소드를 String 타입으로 사용 가능
제네릭 문법
- 제네릭 용어
public class Generic<T> { ... }
Generic<String> stringGeneric = new Generic<>();
- 제네릭 클래스: 제네릭을 사용한 클래스
- T: 타입 변수
- Generic 클래스를 원시 타입이라고 함
- 제네릭의 제한
1. 객체의 static 멤버에 사용할 수 없음: 타입 변수는 인스턴스 변수로 간주됨
static T get() { ... } // 에러
static void set(T t) { ... } // 에러
2. 제네릭 배열을 생성할 수 없음
- 제네릭의 문법
1. 다수의 타입변수 사용 가능
public class Generic<T, U, E> {
public E multiTypeMethod(T t, U u) { ... }
}
Generic<Long, Integer, String> instance = new Generic();
instance.multiTypeMethod(longVal, intVal);
2. 다형성, 즉 상속과 타입의 관계는 그대로 적용됨
3. 와일드 카드를 통해 제네릭의 제한을 구체적으로 정할 수 있음
public class ParkingLot<T extends Car> { ... }
ParkingLot<BMW> bmwParkingLot = new ParkingLot();
ParkingLot<Iphone> iphoneParkingLot = new ParkingLog(); // error!
- 와일드 카드
- <? extends T> : T와 그 자손들만 사용 가능
- <? super T> : T와 그 조상들만 가능
- <?> : 제한 없음
4. 메서드를 스코프로 제네릭을 별도로 선언할 수 있음
= 해당 메서드에서만 적용되는 제네릭 변수를 사용할 수 있음
static <T> void sort(List<T> list, Comparator<? super T> c) { ... }
- 반환 타입 앞에 <> 제네릭을 사용한 경우 해당 메서드에만 적용되는 제네릭 타입 변수 선언
- 제네릭 클래스의 타입 변수를 static 메서드에서는 사용할 수 없었지만, 이 경우에는 해당 메소드에만 적용되므로 사용 가능
- 같은 이름의 변수를 사용해도 제네릭 메소드의 타입변수는 제네릭 클래스의 타입변수와 다름
public class Generic<T, U, E> {
// Generic<T,U,E> 의 T와 아래의 T는 이름만 같을뿐 다른 변수
static <T> void sort(List<T> list, Comparator<? super T> c) { ... }
}
Collection과 제네릭
- 리스트: 추상적 자료구조로서, 순서를 가지고 일렬로 나열한 원소들의 모임
- 검색에는 유리하고 수정/삭제는 불리한 자료구조
- 리스트의 개념적인 명세는 interface 코드로 구현되어 있음
- List 인터페이스의 구현체들이 List의 속성을 가지게 됨
- 제네릭과 함께 List<E> 코드 살펴보기
// 실제 java.util의 List 코드
public interface List<E> extends Collection<E> {
int size();
boolean isEmpty();
...
boolean addAll(Collection<? extends E> c);
boolean add(E e);
...
}
addAll() 메서드의 경우 메서드의 인자는 Collection 타입에 속하면서 List 타입변수 E의 자손 클래스를 원소를 가지고 있어야 함
'[스파르타코딩클럽] > Java 문법 종합반' 카테고리의 다른 글
Chapter 13. 모던 자바(람다, 스트림, Optional) (0) | 2023.10.18 |
---|---|
Chapter 12. 스레드 (0) | 2023.10.18 |
Chapter 10. 예외처리 (0) | 2023.10.17 |
Chapter 9. 인터페이스 (0) | 2023.10.17 |
Chapter 8. 상속 (0) | 2023.10.16 |