[Java] 제네릭(Generic)이란?

제네릭(Generic)이란?


제네릭은 다양한 타입의 데이터와 함께 사용할 수 있게 하는 클래스 및 메서드를 작성할 수 있게 해준다. 그래서 재사용성이 좋은 코드를 작성할 수 있게 해주고, 컴파일 과정에서 타입체크를 해주는 자바(5부터 도입)의 기능 중 하나이다. 

 

다양한 타입의 데이터와 함께 사용할 수 있게 한다는 말이 이해가 잘 되지 않으니 예시 코드로 살펴보자.

public class Box<T> {
    private T content;

    public void put(T content) {
        this.content = content;
    }

    public T get() {
        return content;
    }
}

Box라는 클래스를 <T> 타입으로 선언해주었다. 여기서 <T> 이 모양이 제네릭 표현식이다.

일반적으로 꺾쇠 모양 <> 안에 타입을 명시해준 형태가 제네릭이다.

 

현재 Box라는 클래스는 어떤 타입인지 정확히 명시되어 있지 않다. 한번 Box 객체를 생성해서 사용해 보자.

 

public class Generic {
    public static void main(String[] args) {
        Box<String> boxOfStrings = new Box<>();
        boxOfStrings.put("parcel");
        String content = boxOfStrings.get();
        System.out.println("content = " + content);    // content = parcel

        Box<Integer> boxOfIntegers = new Box<>();
        boxOfIntegers.put(10);
        Integer number = boxOfIntegers.get();
        System.out.println("number = " + number);      // number = 10
    }
}

 

첫 번째 Box는 String용 객체를 생성했고, 두 번째 Box는 Integer용 객체를 생성해서 각각 타입에 맞는 내용물을 저장해서 출력했다.

 

이렇게 제네릭은 하나의 Box 클래스로 두 개의 서로 다른 타입의 내용물을 저장할 수 있어 재사용이 가능한 코드를 작성할 수 있다는 장점이 있다.

 

제네릭의 장점으로 컴파일 시 타입을 체크해 주는 기능이 있다.

이 기능을 아래 예제 코드로 살펴보자.

 

우리는 제네릭을 ArrayList<Integer> 이 형태로 많이 접했을 텐데, 제네릭을 사용하지 않았을 때 코드를 살펴보자

public class Generic {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();

        list.add(10);
        list.add(20);
        list.add("10");

        Integer number = (Integer) list.get(2);

        System.out.println("number = " + number);
    }
}

ArrayList에 Integer와 String을 담고 3번째 자리의 String 형태의 "10"을 꺼내서 Integer 형태로 변환한 다음 저장해도 컴파일 시에는 에러가 발생하지 않는다. 하지만 위 코드는 실행 시 형번환 에러가 발생한다. (컴파일러의 한계)

 

위 코드에서 제네릭을 사용해 ArrayList의 list에 Integr만 저장하겠다고 타입을 작성해 주어 컴파일 시 에러를 체크한다.

ArrayList<Integer> list = new ArrayList();

<Integer> 같이 ArrayList에 타입을 지정해 주면 Integer 이외의 타입을 저장하려고 하면 컴파일 에러가 발생한다.

 

실행 시 에러가 발생하는 것보다 컴파일 시에 에러가 발생하는 것이 개발 초기에 에러를 잡고 수정할 수 있기 때문에 개발 시간을 많이 절약할 수 있기 때문이다.

 

제네릭 사용 장점


1. 제네릭이 형식 안전성을 제공한다.

제네릭을 사용하면 코드가 올바른 유형의 데이터에서만 작동하는지 확인할 수 있다. 이렇게 하면 오류를 방지하고 코드를 더 안정적으로 만들 수 있다.

 

2. 제네릭을 사용해 코드의 재사용성을 높일 수 있다.

일반 클래스 및 메서드를 작성하면 모든 유형의 데이터에 사용할 수 있는 코드를 작성할 수 있습니다. 이렇게 하면 코드가 더 유연하고 재사용 가능해집니다.

 

3. 제네릭이 더 나은 성능을 제공한다.

제네릭을 사용하지 않으면 형변환 과정이 필요할 수 있는데 제네릭을 사용하면 형변환을 피할 수 있어 성능면에서 더 빠르고 효율적인 코드를 작성할 수 있다.

 

 

Reference

자바의 정석 ch12 - https://www.youtube.com/watch?v=QcXLiwZPnJQ