Programming/JAVA

[Java] Generic 이해 하기 - Generic이란

코딩의성지 2021. 10. 25. 18:20

하이..

언어공부를 하다보면 한번쯤은 이 Generic에 의문을 가지는데, 오늘 한번 큰 마음 먹고 정리를 해보려고한다.

 

우리는 다양한 방식으로 Generic을 활용해 오고 있었다.

아래 예제 코드를 보자.

List<Integer> lists = new ArrayList<Integer>();
HashMap<Integer, String> map = new HashMap<Integer, String>();

 

우리는 개발할 때 <> 괄호안에 들어가는 타입을 따로 정해준다. 만약에 저 리스트나 맵이 별도의 타입을 지원해주는 용도로 각각 만들어져 있다고 생각해보자.  그건 정말 비효율적인 내용이 되지 않을까 생각한다.

 

ArrayList를 까보면  아래의 그림처럼 되어있는데,

괄호 안에 E 가 있다. E는 보통 Element를 의미한다. 이처럼 제네릭에서는 다양한 타입들을 약속해놓고 사용하는데 그 내용은 아래와 같다.

타입 설명
<T>  Type
<E> Element
<K> Key
<V> Value
<N> Number

 

이렇게 제네릭을 쓰면 몇가지 장점이 있는데,

먼저 컴파일 단계에서 잘못된 타입으로 인한 에러를 방지할 수 있고 (물론 컴파일단계에서만 형 안정성을 제공함으로, 런타임 단계에서는 안정성을 보장받지는 못한다.)

클래스 외부에서 타입을 지정해주기 때문에 따로 타입을 체크하거나 캐스팅을 해줄 필요가 없다.

그리고 자료구조를 다양한 비슷한 상황에서 상용하는 것처럼 제네릭을 잘 이용하면 코드의 재 사용성이 높아진다.

 

1. 클래스 및 인터페이스 사용 방법

public class GenericTestClass <T> {...}
public Interface GenericTestInterface <T> {...}

기본적으로 위처럼 클래스나 인터페이스를 선언하여 제네릭을 활용할 수 있다. 저기서 선언한 T 타입은 각 블럭안에서 유효하게 동작한다.

여기서 실제로 괄호 안에 들어가는 값은 primitive 타입이 아니라 참조 타입인 Integer, Double. Boolean 등의 Wrapper Type 이 와야하고, 사용자가 정의한 클래스 타입도 올수 가 있다.

 

2. Generic 클래스 생성

실제로 간단하게 제네릭 클래스를 만들어보면 아래와 같다.

class GenericTestClass <E> {
    private E element;

    void set(E element) {
        this.element = element;
    }

    E get() {
        return element;
    }
}

class  GenericTestClass2<K, V> {
    private K key;
    private V value;

    void set(K key, V value) {
        this.key = key;
        this.value = value;
    }

    K getKey() {
        return key;
    }

    V getValue() {
        return value;
    }
}

public class GenericTest {
    public static void main(String[] args){
        GenericTestClass<String> object1 = new GenericTestClass<>();
        object1.set("a");
        System.out.println(object1.get());

        GenericTestClass<Integer> object2 = new GenericTestClass<>();
        object2.set(1000);
        System.out.println(object2.get());

        GenericTestClass2<String, Integer> object3 = new GenericTestClass2<>();
        object3.set("key",123);
        System.out.println("key : " + object3.getKey() +" , value : " + object3.getValue());
    }
}

GenericTestClass 는 파라미터를 하나만 보내 제네릭 타입을 지정해주고, GenericTestClass는 두개를 지정해주는 예제이다.  프로그램을 돌려보면 아래의 결과가 나오는 것을 확인할 수 있다.

 

오늘은 Generic Class 와 InterFace를 생성하고 사용하는 방법을 알아봤다. 다음에는 제네릭 메서드를 사용하는 방법을 포스팅해보도록하겠다.

반응형