본문 바로가기
Everyday Study

2024.07.15 (월) { 제너릭 }

by xogns93 2024. 7. 15.

제너릭 클래스

 

제네릭(Generic) 클래스는 Java에서 데이터 타입을 미리 지정하지 않고, 클래스나 메서드를 정의할 때 타입 파라미터를 사용하여 유연성과 재사용성을 높이는 방법입니다. 제네릭스를 사용하면 여러 타입에 대해 동작하는 클래스나 메서드를 작성할 수 있으며, 컴파일 시 타입 안전성을 보장받을 수 있습니다.

 

제네릭 클래스는 하나 이상의 타입 파라미터를 가지는 클래스입니다. 이 타입 파라미터는 클래스가 인스턴스화될 때 실제 데이터 타입으로 대체됩니다. 제네릭 클래스는 클래스 정의 시점에 타입을 고정하지 않고, 필요할 때 다양한 타입을 사용할 수 있도록 설계됩니다.

 

제네릭 클래스를 정의할 때, 타입 파라미터클래스 이름 바로 뒤에 옵니다.

public class Box<T> {

 

제네릭 클래스의 제약사항

  1. 기본 타입 사용 불가:
    • 제네릭 타입 파라미터로 기본 타입(예: int, char)을 사용할 수 없습니다. 대신, 기본 타입에 대응하는 래퍼 클래스(예: Integer, Character)를 사용해야 합니다.
  2. 타입 파라미터에 대한 제한:
    • 제네릭 타입 파라미터에는 특정 타입을 상속받도록 제한할 수 있습니다. 예를 들어, T extends Number는 T가 Number의 하위 클래스여야 한다는 것을 의미합니다.
  3. 정적 컨텍스트에서의 제네릭 사용 제한:
    • 제네릭 타입 파라미터는 정적 변수나 정적 메서드에서는 사용할 수 없습니다. 이는 제네릭 타입이 인스턴스화될 때 결정되기 때문입니다.

 


제너릭 메서드

 

제너릭 메서드는 자체적인 타입 파라미터를 도입하는 메서드입니다. 타입 파라미터는 메서드 반환 타입 앞에 위치합니다.

이는 제너릭 타입을 선언하는 것과 유사하지만, 제너릭 메서드의 타입 파라미터 범위는 해당 선언된 메서드로 제한됩니다. 정적 및 비정적 제너릭 메서드뿐만 아니라 제너릭 클래스 생성자도 허용됩니다.

 

제네릭 메서드는 메서드 이름 앞에 타입 파라미터를 선언합니다.

public static <T> void printArray(T[] array) {

public class GenericMethodExample {

    // 제네릭 메서드
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.println(element);
        }
    }

    public static void main(String[] args) {
        String[] stringArray = {"Hello", "World"};
        Integer[] integerArray = {1, 2, 3};

        // 제네릭 메서드 호출
        printArray(stringArray); // 문자열 배열 출력
        printArray(integerArray); // 정수 배열 출력
    }
}

위 예제에서 printArray 메서드는 제네릭 메서드로 정의되어, T 타입 파라미터를 사용하여 다양한 타입의 배열을 처리할 수 있습니다.


제네릭 클래스와 메서드

제네릭 클래스와 제네릭 메서드는 함께 사용될 수 있습니다. 제네릭 클래스는 클래스 전체에서 사용할 수 있는 타입 파라미터를 도입하며, 제네릭 메서드는 메서드 수준에서 타입 파라미터를 도입합니다.

public class GenericClass<T> {
    private T value;

    public GenericClass(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }

    // 제네릭 메서드
    public <U> void printPair(U otherValue) {
        System.out.println("Value: " + value + ", Other Value: " + otherValue);
    }

    public static void main(String[] args) {
        GenericClass<String> stringInstance = new GenericClass<>("Hello");
        stringInstance.printPair(123); // 문자열과 정수 출력

        GenericClass<Integer> integerInstance = new GenericClass<>(456);
        integerInstance.printPair("World"); // 정수와 문자열 출력
    }
}

위 예제에서 GenericClass는 제네릭 클래스이며, printPair 메서드는 제네릭 메서드입니다. printPair 메서드는 U 타입 파라미터를 도입하여 T와 U 두 가지 타입을 함께 처리할 수 있습니다.

 


정적 제네릭 메서드

정적 메서드도 제네릭 메서드로 정의될 수 있습니다. 정적 메서드는 클래스의 인스턴스가 아닌 클래스 자체에 속하므로, 정적 메서드에서 사용하는 제네릭 타입 파라미터는 클래스의 제네릭 타입 파라미터와 독립적입니다.

public class StaticGenericMethodExample {

    // 정적 제네릭 메서드
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.println(element);
        }
    }

    public static void main(String[] args) {
        String[] stringArray = {"Hello", "World"};
        Integer[] integerArray = {1, 2, 3};

        // 정적 제네릭 메서드 호출
        printArray(stringArray); // 문자열 배열 출력
        printArray(integerArray); // 정수 배열 출력
    }
}

위 예제에서 printArray는 정적 제네릭 메서드로 정의되어, 다양한 타입의 배열을 처리할 수 있습니다.

 


 

제네릭 생성자

 

제네릭 생성자는 제네릭 타입 파라미터를 사용하여 인스턴스를 생성할 수 있습니다. 제네릭 클래스의 생성자뿐만 아니라, 일반 클래스의 생성자도 제네릭으로 정의할 수 있습니다.

public class GenericConstructorExample {
    private String value;

    // 제네릭 생성자
    public <T> GenericConstructorExample(T value) {
        this.value = value.toString();
    }

    public String getValue() {
        return value;
    }

    public static void main(String[] args) {
        GenericConstructorExample example1 = new GenericConstructorExample(123);
        GenericConstructorExample example2 = new GenericConstructorExample("Hello");

        System.out.println("Example 1 Value: " + example1.getValue()); // "123"
        System.out.println("Example 2 Value: " + example2.getValue()); // "Hello"
    }
}

위 예제에서 GenericConstructorExample 클래스는 제네릭 생성자를 가지고 있으며, 다양한 타입의 값을 받아 문자열로 변환하여 저장합니다.