[JAVA] 제네릭(Generic)타입

현서황·2024년 10월 16일

자바에서 클래스나 메서드를 정의할 때, 특정 데이터 타입에 의존하지 않고 다양한 타입을 처리할 수 있도록 만드는 방법이다.
제네릭을 사용하면 데이터 타입을 일반화시켜 코드의 재사용성과 타입 안전성을 높일 수 있다. 제네릭을 통해 컴파일 시점에 타입을 확정하고, 그로인해 잘못된 타입 사용을 방지할 수 있다.

제네릭은 클래스나 메서드를 정의할 때 사용되며, 그 안에서 다룰 데이터 타입을 나중에 지정할 수 있도록 해준다. 예를 들어 특정 클래스가 Integer,String과 같은 다양한 데이터 타입을 처리해야하는 경우, 제네릭을 사용하면 같은 코드를 중복 작성하지 않고 한 번에 다양한 데이터 타입을 처리할 수 있다.

제네릭 타입의 문법

class 클래스이름<T> {
    // 클래스 내용
}

여기서 T는 제네릭 타입 매개변수로 Type을 나타내는 약어이다. T 외에도 E, K, V 등 다양한 문자를 사용할 수 있다.
하지만 일반적으로는 T를 많이 사용한다.

사용 예시

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) {
        // String 타입의 Box
        Box<String> stringBox = new Box<>();
        stringBox.setItem("Hello");
        System.out.println(stringBox.getItem());  // 출력: Hello

        // Integer 타입의 Box
        Box<Integer> intBox = new Box<>();
        intBox.setItem(123);
        System.out.println(intBox.getItem());  // 출력: 123
    }
}

제네릭 메서드 예시

  • 클래스 뿐만 아니라 메서드에도 적용할 수 있다. 제네릭 메서드는 메서드 정의에서 제네릭 타입을 사용하는 것이다.
public class GenericMethodExample {

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

    public static void main(String[] args) {
        // Integer 배열 출력
        Integer[] intArray = {1, 2, 3, 4, 5};
        printArray(intArray);

        // String 배열 출력
        String[] strArray = {"A", "B", "C", "D"};
        printArray(strArray);
    }
}

제네릭의 장점

  1. 타입 안전성(Type Safety)
  • 제네릭을 사용하면 컴파일 시점에서 타입 검사를 하기 때문에 잘못된 타입을 사용하는 오류를 방지할 수 있다. 예를 들어, 제네릭을 사용하지 않고 Object 타입을 사용할 경우, 각 데이터를 처리할 때마다 타입 변환(casting)을 해야하고, 잘못된 변환 시 런타임 오류가 발생할 수 있다.
  • 제네릭 사용 시 미리 타입을 지정하고 잘못된 타입의 데이터가 들어가는 것을 방지할 수 있다.
  1. 코드 재사용성
  • 제네릭을 사용하면 하나의 클래스나 메서드로 다양한 데이터 타입을 처리할 수 있으므로, 중복 코드를 줄이고 코드 재사용성을 높일 수 있다.
  1. 캐스팅을 줄임
  • 제네릭을 사용하지 않으면 Object로 데이터를 처리하게 되므로 데이터 타입에 맞게 형변환(casting)을 해야한다. 제네릭을 사용하면 이 과정이 생략되어 코드가 더욱 간결해진다.

제네릭을 사용하지 않았을 때의 문제점

제네릭이 없다면 모든 객체를 Object로 처리해야하며, 이로인해 불필요한 형변환이 필요하게 된다.

public class NonGenericBox {
    private Object item;

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

    public Object getItem() {
        return item;
    }

    public static void main(String[] args) {
        NonGenericBox box = new NonGenericBox();
        box.setItem("Hello");
        
        // 형 변환 필요
        String item = (String) box.getItem(); 
        System.out.println(item);
        
        // 형 변환 오류 가능성
        box.setItem(123);
        String wrongType = (String) box.getItem();  // 실행 시 ClassCastException 발생
    }
}
  • setItem() 메서드는 매개변수로 Object 타입을 받기 때문에 어떤 객체든 저장할 수 있다. 예를 들어, String 객체도 저장할 수 있고, Integer 객체도 저장할 수 있다.
  • getItem() 메서드는 저장된 객체를 반환하는데, 반환 타입이 Object이다. 이 반환된 객체를 사용할 때, 해당 객체를 구체적인 타입(예: String)으로 형 변환(casting) 해야한다.
  • 처음에 setItem("Hello")String 객체를 저장했고, 이를 String으로 형 변환하여 문제없이 사용했다. 하지만 두 번째로 setItem(123)Integer 객체를 저장하고 나서 이를 String으로 잘못 형 변환하려고 하므로, ClassCastException이 발생하게 된다.

오류의 원인

  • setItem()을 통해 어떤 타입의 객체든 저장할 수 있지만, getItem으로 객체를 꺼내올 때 그 객체가 원래 어떤 타입이었는지 알 수 없기 때문에 잘못된 타입으로 형 변환을 시도할 경우 런타임 오류가 발생한다.
  • Integer객체는 String으로 직접 형변환을 할 수 없다.
    • 형변환은 일반적으로 두 클래스가 상속관계에 있을 때만 가능하다.
    • 예를 들어, Integer는 Object를 상속받기 때문에 Object로 형 변환이 가능하다. 그러나 Integer와 String은 전혀 상관없는 클래스이므로 직접 형변환을 시도하면 ClassCastException이 발생한다.

Integer를 String으로 변환 방법

  • String.valueOf()메서드를 사용해야 한다. 이 메서드는 intInteger 값을 문자열로 반환해준다.
Integer intObj = 123;
String str = String.valueOf(intObj);
System.out.println(str);  // 출력: "123"
  • Integer.toString()메서드를 통해 Integer 객체의 값을 문자열로 변환할 수 있다.
Integer intObj = 123;
String str = intObj.toString();
System.out.println(str);  // 출력: "123"
  • 문자열 결합 연산자(+) 사용
    숫자를 문자열과 더하면 자동으로 문자열로 변환된다.
Integer intObj = 123;
String str = intObj + "";  // 문자열 결합
System.out.println(str);  // 출력: "123"

String을 Integer로 변환하는 방법

  • Integer.parseInt() 사용
    int형으로 변환해준다.
String str = "123";
int number = Integer.parseInt(str);
System.out.println(number);  // 출력: 123
  • Integer.valueOf() 사용
    객체형(Integer)로 변환해줌.
String str = "123";
Integer number = Integer.valueOf(str);
System.out.println(number);  // 출력: 123
profile
노는 게 제일 좋은 뽀로로

0개의 댓글