Light Blue Pointer
본문 바로가기
Developing/TIL(Develop)

제네릭(Generic)이란

by Greedy 2024. 5. 31.

Java에서 제네릭(Generic)은 클래스, 인터페이스, 메서드 등에 사용할 수 있는 타입 매개변수화 기법을 말한다.

제네릭을 사용하면 컴파일 시 타입을 체크할 수 있으며, 코드의 재사용성을 높이고, 타입 안정성을 보장할 수 있다.

제네릭은 자바 5에서 도입되었으며, 주로 컬렉션 프레임워크에서 많이 사용된다.

제네릭의 주요 특징

타입 안전성(Type Safety) 보장

컴파일 시점에 타입을 체크하여 런타임 에러를 줄일 수 있다

타입 캐스팅 제거

제네릭을 사용하면 불필요한 타입 캐스팅을 제거할 수 있다

코드 재사용성 증가

다양한 타입에 대해 동일한 코드를 사용할 수 있다

제네릭의 기본 사용법

제네릭 클래스

제네릭 클래스는 클래스 선언 시 타입 매개변수를 사용하여 정의할 수 있다

다음은 제네릭 클래스를 사용하는 예제이다

public class Box<T> {
    private T item;

    public void setItem(T item) {
        this.item = item;
    }

    public T getItem() {
        return item;
    }

    public static void main(String[] args) {
        Box<String> stringBox = new Box<>();
        stringBox.setItem("Hello");
        System.out.println(stringBox.getItem());

        Box<Integer> integerBox = new Box<>();
        integerBox.setItem(123);
        System.out.println(integerBox.getItem());
    }
}

위의 예제에서 Box<T>는 제네릭 클래스이다

T는 타입 매개변수로, Box 클래스 내부에서 실제 타입으로 대체된다

제네릭 메서드

제네릭 메서드는 메서드 선언에 타입 매개변수를 사용할 수 있다

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, 4, 5};
        String[] stringArray = {"A", "B", "C", "D", "E"};

        printArray(intArray);
        printArray(stringArray);
    }
}

위의 예제에서 printArray 메서드는 제네릭 메서드이다

T는 메서드의 타입 매개변수이다

제네릭 인터페이스

제네릭 인터페이스는 인터페이스 선언 시 타입 매개변수를 사용할 수 있다

public interface Pair<K, V> {
    public K getKey();
    public V getValue();
}

class OrderedPair<K, V> implements Pair<K, V> {
    private K key;
    private V value;

    public OrderedPair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public K getKey() { return key; }

    @Override
    public V getValue() { return value; }

    public static void main(String[] args) {
        Pair<String, Integer> p1 = new OrderedPair<>("One", 1);
        Pair<String, String> p2 = new OrderedPair<>("Hello", "World");

        System.out.println("Pair 1: " + p1.getKey() + " = " + p1.getValue());
        System.out.println("Pair 2: " + p2.getKey() + " = " + p2.getValue());
    }
}

위의 예제에서 Pair<K, V>는 제네릭 인터페이스이며, OrderedPair<K, V>는 이를 구현한 제네릭 클래스이다

제네릭 타입 제한 (Bounded Type Parameters)

제네릭 타입에 특정 타입만 허용하도록 제한할 수 있다

이는 extends 키워드를 사용하여 구현할 수 있다

public class BoundedTypeParameterExample {
    public static <T extends Number> void printNumber(T number) {
        System.out.println("Number: " + number);
    }

    public static void main(String[] args) {
        printNumber(123);      // Integer
        printNumber(45.67);    // Double
        // printNumber("123"); // 컴파일 오류
    }
}

위의 예제에서 T extends Number는 T가 Number 클래스 또는 그 하위 클래스여야 함을 의미한다

와일드카드(Generic Wildcards)

와일드카드는 제네릭 타입을 보다 유연하게 사용할 수 있도록 도와준다

무제한 와일드카드 <?>

상한 경계 와일드카드 <? extends Type>

하한 경계 와일드카드 <? super Type>

와일드카드 예제

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

public class WildcardExample {
    public static void printList(List<?> list) {
        for (Object elem : list) {
            System.out.print(elem + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        List<Integer> intList = new ArrayList<>();
        intList.add(1);
        intList.add(2);
        intList.add(3);

        List<String> stringList = new ArrayList<>();
        stringList.add("A");
        stringList.add("B");
        stringList.add("C");

        printList(intList);
        printList(stringList);
    }
}

위의 예제에서 printList 메서드는 무제한 와일드카드를 사용하여 모든 타입의 리스트를 인자로 받을 수 있다

요약

제네릭은 자바에서 타입을 매개변수화하여 코드의 재사용성을 높이고, 컴파일 시 타입 체크를 통해 타입 안전성을 보장하는 강력한 기법이다

제네릭 클래스, 제네릭 메서드, 제네릭 인터페이스, 와일드카드 등 다양한 기능을 통해 복잡한 타입 관계를 표현할 수 있다

이를 적절히 사용하면 더 안전하고 유지보수하기 쉬운 코드를 작성할 수 있다

'Developing > TIL(Develop)' 카테고리의 다른 글

ktlint 자동적용 안 되는 경우 해결법  (0) 2024.06.02
String과 StringBuilder, StringBuffer의 차이  (0) 2024.05.31
Java volatile / synchronized  (0) 2024.05.31
JavaBean  (1) 2024.05.31
Java의 다형성(Polymorphism)  (0) 2024.05.31