Java의 제너릭(Generic) 타입은 클래스나 메서드에서 사용할 데이터 타입을 컴파일 시에 지정할 수 있도록 하는 기능입니다. 제너릭은 타입 안정성을 제공하고, 캐스팅 작업을 줄여 코드를 더 간결하고 안전하게 만듭니다.
1. 제너릭 클래스
class Box<T> {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
public class GenericClassExample {
public static void main(String[] args) {
// Integer 타입의 Box
Box<Integer> intBox = new Box<>();
intBox.setValue(123);
System.out.println("Integer Box: " + intBox.getValue());
// String 타입의 Box
Box<String> strBox = new Box<>();
strBox.setValue("Hello");
System.out.println("String Box: " + strBox.getValue());
}
}
** Java의 제네릭 클래스는 객체가 생성될 때 타입이 결정됩니다. 제네릭 클래스의 타입 파라미터는 객체를 인스턴스화할 때 전달되며, 컴파일 타임에 타입이 고정됩니다.
2. 제너릭 메소드
public class GenericMethodExample {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3};
String[] strArray = {"A", "B", "C"};
printArray(intArray); // 출력: 1 2 3
printArray(strArray); // 출력: A B C
}
}
** 제네릭 메서드의 타입 결정 시점
- 타입 추론: 컴파일러가 메서드를 호출하는 문맥에서 전달된 인자를 보고 타입을 자동으로 추론합니다.
- 명시적 타입 지정: 호출 시 타입을 명시할 수도 있으며, 이 경우 타입 추론 대신 명시된 타입을 사용합니다.
public class GenericMethodExample {
public static <T> void print(T item) {
System.out.println(item);
}
public static void main(String[] args) {
print("Hello"); // 컴파일러가 T를 String으로 추론
print(123); // 컴파일러가 T를 Integer로 추론
}
}
public class GenericMethodExample {
public static <T> void print(T item) {
System.out.println(item);
}
public static void main(String[] args) {
GenericMethodExample.<String>print("Hello"); // T를 String으로 명시
}
}
3. 제너릭 타입 제한 (Bounded Type Parameters)
class NumberBox<T extends Number> {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public double getDoubleValue() {
return value.doubleValue();
}
}
public class BoundedTypeExample {
public static void main(String[] args) {
NumberBox<Integer> intBox = new NumberBox<>();
intBox.setValue(123);
System.out.println("Double Value: " + intBox.getDoubleValue()); // 출력: 123.0
NumberBox<Double> doubleBox = new NumberBox<>();
doubleBox.setValue(45.67);
System.out.println("Double Value: " + doubleBox.getDoubleValue()); // 출력: 45.67
}
}
4. 와일드카드 (Wildcard)
와일드카드는 제너릭 타입을 보다 유연하게 사용하도록 도와줍니다.
<?> | 임의의 타입 (모든 타입 가능) |
<? extends 상위클래스> | 상위 클래스 또는 그 하위 타입만 허용 |
<? super 하위클래스> | 하위 클래스 또는 그 상위 타입만 허용 |
import java.util.ArrayList;
import java.util.List;
public class WildcardExample {
// 상한 제한
public static void printNumbers(List<? extends Number> list) {
for (Number number : list) {
System.out.println(number);
}
}
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
List<Double> doubleList = new ArrayList<>();
doubleList.add(1.1);
doubleList.add(2.2);
printNumbers(intList); // 출력: 1 2
printNumbers(doubleList); // 출력: 1.1 2.2
}
}
'WEB개발 > JAVA' 카테고리의 다른 글
Daemon Thread vs User Thread (0) | 2025.02.21 |
---|---|
CyclicBarrier, CountDownLatch (0) | 2025.02.21 |
메서드 참조, function, consumer, supplier (0) | 2024.12.18 |
[JAVA] 메모리 스택, 힙 (0) | 2022.10.31 |
[JAVA] Thread-Safe, Concurrent Collection class, Double Checked Locking (0) | 2021.09.23 |