PHpullh
학습 라이브러리/Java/Generic — 타입 경계 & 와일드카드

JAVA · 기초 문법

Generic — 타입 경계 & 와일드카드

제네릭의 타입 경계(extends, super)와 와일드카드로 유연한 API를 설계합니다.

기초 문법중급GenericextendssuperwildcardPECS

핵심 설명

제네릭의 타입 경계(extends, super)와 와일드카드로 유연한 API를 설계합니다.

Java code

import java.util.*;

public class Generics {
    // 상한 경계 — T는 Number 또는 그 하위 타입
    static <T extends Number & Comparable<T>> T max(List<T> list) {
        return list.stream()
            .max(Comparator.naturalOrder())
            .orElseThrow();
    }

    // 와일드카드 — ? extends (공변, 읽기 전용)
    static double sumList(List<? extends Number> list) {
        return list.stream().mapToDouble(Number::doubleValue).sum();
    }

    // 와일드카드 — ? super (반공변, 쓰기 가능)
    static void addNumbers(List<? super Integer> list) {
        list.add(1); list.add(2); list.add(3);
    }

    // PECS 원칙: Producer Extends, Consumer Super
    static <T> void copy(List<? extends T> src, List<? super T> dst) {
        for (T t : src) dst.add(t);
    }

    // 제네릭 클래스
    static class Pair<A, B> {
        private final A first;
        private final B second;

        Pair(A first, B second) { this.first = first; this.second = second; }

        public A first()  { return first; }
        public B second() { return second; }

        // 정적 팩토리
        static <A, B> Pair<A, B> of(A a, B b) { return new Pair<>(a, b); }

        @Override public String toString() {
            return "(%s, %s)".formatted(first, second);
        }
    }

    public static void main(String[] args) {
        System.out.println(max(List.of(3, 1, 4, 1, 5)));  // 5
        System.out.println(sumList(List.of(1, 2.5, 3L))); // 6.5

        List<Number> nums = new ArrayList<>();
        addNumbers(nums);
        System.out.println(nums); // [1, 2, 3]

        var pair = Pair.of("Java", 21);
        System.out.println(pair); // (Java, 21)
    }
}

학습 팁

PECS 원칙: 데이터를 제공(Producer)한다면 extends, 데이터를 소비(Consumer)한다면 super를 사용하세요.

주의할 점

제네릭 배열 생성(new T[])은 컴파일 에러입니다. List를 사용하거나 (T[]) new Object[n]으로 우회합니다(비권장).

자주 묻는 질문

Generic — 타입 경계 & 와일드카드란 무엇인가요?

제네릭의 타입 경계( extends , super )와 와일드카드로 유연한 API를 설계합니다.

Generic — 타입 경계 & 와일드카드 학습 시 주의할 점은 무엇인가요?

제네릭 배열 생성( new T[] )은 컴파일 에러입니다. List 를 사용하거나 (T[]) new Object[n] 으로 우회합니다(비권장).