1. Generics란?
Generics는 중복된 코드 제거와 타입 안정성을 보장하는 자바의 강력한 기능입니다. 주로 클래스나 메서드에 적용되며, 코드의 재사용성을 높이고 타입 체크를 컴파일 시점에 수행하여 런타임 오류를 줄이는 데 목적이 있습니다. 예를 들어, 클래스 이름 뒤의 <>
문법 안에 타입 변수를 지정하여 다양한 타입을 유연하게 처리할 수 있습니다.
예시
public class Box<T> {
private T item;
public void set(T item) { this.item = item; }
public T get() { return item; }
}
여기서 T
는 타입 변수로, 어떤 타입이든 올 수 있습니다.
2. Generics의 장점
- 코드 중복 제거 : 하나의 클래스나 메서드를 여러 타입에 대응시키면서 중복된 코드 작성이 필요 없어집니다.
- 타입 안정성 유지 : 컴파일 시점에 타입 체크가 이루어져 런타임 오류를 줄일 수 있습니다.
- 유연한 재사용성 : 여러 타입에 대해 동일한 코드 흐름을 유지할 수 있어 코드의 유연성을 제공합니다.
3. Wildcards(와일드 카드)
Generics에서는 특정 타입의 제한을 설정할 때 와일드 카드를 사용할 수 있습니다. 와일드 카드는 <? extends T>
, <? super T>
, <?>
로 나뉘어 사용됩니다.
- <? extends T> : T와 그 자손 타입만 사용 가능
- <? super T> : T와 그 조상 타입만 사용 가능
- <?> : 제한 없음
public void process(List<? extends Number> list) {
// Number와 그 자손(Integer, Double 등)만 허용
}
알게 된 점
와일드 카드는 처음에는 복잡하게 느껴졌지만, 결국 상속 관계와 유사하게 타입의 경계를 설정하는 데 매우 유용하다는 것을 깨달았습니다. 특히 자손이나 조상을 제한하는 기능은 다양한 상황에서 활용 가능성이 높다는 것을 알게 됐습니다.
4. Generics의 제한 사항
- static 멤버에서 사용 불가 : 제네릭 타입 변수는 인스턴스 변수로 취급되기 때문에, 모든 객체에 동일하게 동작해야 하는 static 필드에서는 사용할 수 없습니다.
public class Box<T> { private static T item; // 컴파일 오류 발생 }
배운 점
- static 멤버는 클래스 레벨에서 관리되는 특성상, 제네릭 타입 변수를 사용할 수 없는 것은 이해가 됩니다. 이는 자바의 static 특성과 객체 지향성 간의 관계를 다시 한번 생각하게 하는 계기가 되었습니다.
- 배열 생성 불가 : 제네릭 타입으로 배열을 생성할 수 없습니다. 예시)
List<String>[] stringLists = new ArrayList<String>[10]; // 컴파일 오류
- 다형성 적용 : 제네릭은 다형성에 그대로 적용되며, 부모 타입을 제네릭으로 지정하고 자식 클래스를 사용할 수 있습니다.
5. TIP & 정리
TIP
- 제네릭 타입 변수는 대개 한 글자로 표현 :
T
(Type),E
(Element),K
(Key),V
(Value) 등을 주로 사용합니다. 이는 가독성을 높이는 데 도움을 줍니다. - 와일드 카드의 적극적인 활용 :
<? extends T>
와<? super T>
를 적극 활용하면 제네릭의 범위를 적절히 제한할 수 있습니다. 특히 상위 클래스나 하위 클래스에만 적용하고자 할 때 유용합니다. - 제네릭과 컬렉션의 궁합 : List, Set, Map 같은 컬렉션 프레임워크에서 제네릭은 필수적입니다. 컬렉션과 함께 사용할 때 제네릭을 활용하면 더 안전한 코드를 작성할 수 있습니다.
- 코드 재사용성을 극대화 : 제네릭을 사용하면, 다양한 타입에 대해 같은 로직을 적용할 수 있어, 코드의 유지 보수성과 재사용성을 극대화할 수 있습니다.
정리
Generics는 코드의 중복을 줄이면서도 타입 안정성을 유지하는 강력한 도구라고 생각합니다. 특히 타입 안전성과 재사용성 측면에서 매우 유용하며, 이를 통해 자바의 코드 품질을 한층 더 높일 수 있다고 보여집니다.
'JAVA' 카테고리의 다른 글
(JAVA) 프로세스와 쓰레드 개념 이해하기 (0) | 2024.09.24 |
---|---|
(JAVA) Wrapper 기본 개념 이해하기 (0) | 2024.09.23 |
(JAVA) 예외처리 알아가기 (0) | 2024.09.20 |
(JAVA) 다중상속과 인터페이스 알아보기 (0) | 2024.09.20 |
(JAVA) 추상클래스의 개념 + instanceof 이해하기 (0) | 2024.09.20 |