제네릭(Generics) 계념
2024. 6. 25. 21:03ㆍJava/기초
제네릭(Generics)
- 자바에서 타입을 매개변수로 사용할 수 있게 하는 기능으로, 코드의 재사용성을 높이고, 타입 안정성을 보장하며, 컴파일 시 타입 체크를 강화할 수 있습니다.
- 제네릭을 사용하면 클래스나 메서드를 정의할 때 구체적인 데이터 타입을 지정하지 않고, 사용할 때 타입을 지정할 수 있습니다. 이는 코드의 가독성을 높이고, 타입 캐스팅과 관련된 오류를 줄이는 데 도움을 줍니다.
제네릭 클래스
public class Box<T> {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
// 사용 예
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
String content = stringBox.getContent();
System.out.println(content); // 출력: Hello
- 여기서 T는 타입 매개변수입니다. Box 클래스는 T 타입의 객체를 담을 수 있으며, 실제 사용 시에는 T가 구체적인 타입(예: String)으로 대체됩니다.
제네릭 메서드
public class Util {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
}
// 사용 예
Integer[] intArray = {1, 2, 3, 4, 5};
String[] stringArray = {"A", "B", "C"};
Util.printArray(intArray); // 출력: 1 2 3 4 5
Util.printArray(stringArray); // 출력: A B C
- 메서드 선언 시 <T>를 사용하여 타입 매개변수를 지정하고, 메서드 본문에서 T를 사용할 수 있습니다.
제네릭 타입 제한 (Bounded Type Parameters)
public class NumberBox<T extends Number> {
private T number;
public void setNumber(T number) {
this.number = number;
}
public T getNumber() {
return number;
}
public double doubleValue() {
return number.doubleValue();
}
}
// 사용 예
NumberBox<Integer> integerBox = new NumberBox<>();
integerBox.setNumber(10);
System.out.println(integerBox.doubleValue()); // 출력: 10.0
NumberBox<Double> doubleBox = new NumberBox<>();
doubleBox.setNumber(3.14);
System.out.println(doubleBox.doubleValue()); // 출력: 3.14
- 여기서 T extends Number는 T가 Number 클래스의 서브클래스여야 함을 나타냅니다.
- 자주 사용하는 타입인자
- <E> : Element
- <N> : Number
- <R> : Result
- <V> : Value
- <K> : Key
- <T> : Type
와일드카드 (Wildcards)
- 제네릭에서는 ?를 사용하여 와일드카드를 표현할 수 있습니다. 와일드카드는 제네릭 타입의 유연성을 높이기 위해 사용됩니다. 와일드카드는 다음과 같이 세 가지 형태로 사용할 수 있습니다:
- 제한 없는 와일드카드: <?>
- 상한 경계 와일드카드: <? extends Type>
- 하한 경계 와일드카드: <? super Type>
public static void printList(List<?> list) {
for (Object elem : list) {
System.out.println(elem);
}
}
public static void main(String[] args) {
List<Integer> intList = Arrays.asList(1, 2, 3);
List<String> strList = Arrays.asList("one", "two", "three");
printList(intList); // 출력: 1 2 3
printList(strList); // 출력: one two three
}
- 와일드카드를 사용하면 다양한 타입의 리스트를 하나의 메서드로 처리할 수 있습니다.
- 제네릭을 사용하면 코드의 재사용성을 높이고, 타입 안정성을 보장하며, 컴파일 시 타입 체크를 강화할 수 있어, 보다 안전하고 유지보수하기 쉬운 코드를 작성할 수 있습니다.