티스토리 뷰

Java

[Java] Bounded WildCard

snail voyager 2025. 3. 3. 00:33
728x90
반응형

Bounded Wildcard (? extends T, ? super T)

제네릭의 타입 파라미터를 특정 범위로 제한하는 기능

와일드카드(?)를 사용하면 다양한 타입을 허용할 수 있지만, 어떤 타입까지 허용할지를 제어하기 위해 extends 또는 super를 사용

? extends T (상한 제한, Upper Bounded Wildcard)

import java.util.List;
import java.util.ArrayList;

class Animal {
    void sound() {
        System.out.println("동물이 소리를 냅니다.");
    }
}

class Dog extends Animal {
    void sound() {
        System.out.println("멍멍!");
    }
}

class Cat extends Animal {
    void sound() {
        System.out.println("야옹!");
    }
}

public class UpperBoundWildcard {
    // ? extends Animal → Animal과 그 하위 클래스만 허용
    public static void printAnimalSounds(List<? extends Animal> list) {
        for (Animal a : list) {
            a.sound();  // ✅ 읽기(호출)는 가능
        }
        // list.add(new Dog()); ❌ 컴파일 오류 (쓰기 불가능)
    }

    public static void main(String[] args) {
        List<Dog> dogs = new ArrayList<>();
        dogs.add(new Dog());

        List<Cat> cats = new ArrayList<>();
        cats.add(new Cat());

        printAnimalSounds(dogs); // ✅ 가능
        printAnimalSounds(cats); // ✅ 가능
    }
}
  • T 또는 T의 하위 클래스만 허용
  • 읽기(값 가져오기)는 가능하지만, 쓰기(값 추가)는 제한됨
  • 하위 클래스 중 어떤 타입이 들어올지 정확하지 않기 때문

? super T (하한 제한, Lower Bounded Wildcard)

import java.util.List;
import java.util.ArrayList;

public class LowerBoundWildcard {
    // ? super Integer → Integer와 그 상위 클래스 (Number, Object 등) 허용
    public static void addNumbers(List<? super Integer> list) {
        list.add(10);
        list.add(20);
        list.add(30);
        // Integer 이하의 타입은 추가 가능

        Object obj = list.get(0); // ✅ 읽을 때 Object 타입으로 처리
        // Integer num = list.get(0); ❌ 컴파일 오류 (정확한 타입 알 수 없음)
    }

    public static void main(String[] args) {
        List<Integer> intList = new ArrayList<>();
        List<Number> numList = new ArrayList<>();
        List<Object> objList = new ArrayList<>();

        addNumbers(intList); // ✅ 가능
        addNumbers(numList); // ✅ 가능
        addNumbers(objList); // ✅ 가능
    }
}
  • T 또는 T의 상위 클래스만 허용
  • 쓰기(값 추가)는 가능하지만, 읽기(값 가져오기)는 Object 타입으로 처리됨
  • 어떤 상위 클래스가 올지 모르므로 정확한 타입을 보장할 수 없음

PECS(Producer Extends, Consumer Super)

? extends T (Producer) → 데이터를 제공할 때 (읽기 전용)

? super T (Consumer) → 데이터를 저장할 때 (쓰기 전용)

복사 유틸리티 메서드

import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class PECSExample {
    // `src` (데이터 제공) → `? extends T`
    // `dest` (데이터 저장) → `? super T`
    public static <T> void copy(List<? super T> dest, List<? extends T> src) {
        for (T item : src) {
            dest.add(item);  // ✅ 읽은 데이터를 저장
        }
    }

    public static void main(String[] args) {
        List<Integer> src = Arrays.asList(1, 2, 3, 4, 5);
        List<Number> dest = new ArrayList<>();

        copy(dest, src);  // ✅ 가능 (Integer → Number)
        System.out.println(dest); // 출력: [1, 2, 3, 4, 5]
    }
}
  • src에서 데이터를 읽을 때 → ? extends T 사용
  • dest에 데이터를 쓸 때 → ? super T 사용

제네릭 정렬 메서드

import java.util.Collections;
import java.util.List;

public class SortExample {
    // T가 Comparable을 구현한 타입이어야 함
    public static <T extends Comparable<T>> void sortList(List<T> list) {
        Collections.sort(list); // ✅ Comparable을 구현한 타입만 정렬 가능
    }

    public static void main(String[] args) {
        List<Integer> numbers = List.of(5, 3, 8, 1, 2);
        List<String> words = List.of("banana", "apple", "cherry");

        // sortList(numbers); // ❌ List.of()는 Immutable List라 정렬 불가능
        // sortList(words); // ❌ 마찬가지로 불가능

        // ✅ Mutable List로 변경 후 사용
        List<Integer> numList = new ArrayList<>(numbers);
        List<String> wordList = new ArrayList<>(words);

        sortList(numList);
        sortList(wordList);

        System.out.println(numList); // 출력: [1, 2, 3, 5, 8]
        System.out.println(wordList); // 출력: [apple, banana, cherry]
    }
}
  • ? extends Comparable<T>를 사용하여 정렬 가능하도록 만듦
  • List<T>가 Comparable을 구현하는지 확인

 

728x90
반응형

'Java' 카테고리의 다른 글

[Java] DIP (Dependency Inversion Principle)  (0) 2025.03.03
[Java] Generic  (0) 2025.03.03
[Java] try-with-resources  (0) 2025.03.01
[Java] JSON Jackson @JsonProperty  (0) 2025.02.24
[Java] OpenCSV  (0) 2025.01.26
반응형
300x250