본문 바로가기

Java

제네릭(generic) & 컨테이너



제네릭(generic) 
우리가 만든 코드(code)가 특정 인터페이스나 클래스가 아닌 "어떤 미지정 타입" 과 동작 할 수 있도록 더욱 일반화된 코드를 작성하기 위해 나타난 개념이다. 파라미터화 타입(parameterized type)의 개념, 다수의 타입을 허용. 파리미터화 타입의 인스턴스를 생성하면 캐스팅이 이루어질 것이고, 타입이 정확한지 컴파일 시점에서 확인된다.

타입 파라미터(type parameter) - 나중에 결정될 수 있는 미지정 타입.
클래스명 다음에 꺽쇠 괄호 "<>"를 붙여서 그 안에 타입 파라미터를 넣는다.

ex)

1. 클래스 작성법

class 클래스명<타입 파라미터> {
타입 파라미터 변수;
}

class Foo<T> {
T var;
}

2. 인스턴스 생성

클래스명<실제 사용 할 타입 파라미터> 인스턴스명 = new 클래스명<실제 사용 할 타입 파라미터>();

Foo<cat> f = new Foo<cat>();


제네릭의 개념이 없는 일반적인 클래스를 사용하기 위해 객체를 생성하고 메소드를 사용 할 때에는 컴파일 에러가 나지 않도록 때에 따라서 업캐스팅을 해주어야 하는 상황이 발생 할 수 있다. 하지만 제네릭의 개념이 있는 즉, 타입 파라미터를 사용한 클래스는 이 후에 객체를 생성하여 사용할 때 따로 업캐스팅을 해줄 필요가 없어진다. 컴파일 시점에서 컴파일러가 알아서 처리 해 주기 때문이다.

제네릭은 컨테이너 클래스를 생성하는데 많이 사용될 것이다.

컨테이너는 우리가 사용하는 객체를 저장하는 곳으로서 비슷한 배열이 있지만 이에 비해 더욱 유연하며 다른 특성들을 갖기 때문에 객체 저장등에 많이 쓰이는 클래스 라이브러리이다.

제네릭 개념을 이용하여 컨테이너를 사용한 클래스 작성 예제
//FilledListMaker.java

import java.util.*;

public class FilledListMaker<T> { // 클래스에 타입 파라미터 사용
List<T> create(T t, int n) { // 객체를 생성할 때 타입이 지정된다
List<T> result = new ArrayList<T>();
for(int i = 0; i < n; i++)
result.add(t);
return result;
}
public static void main(String[] args) {
FilledListMaker<String> stringMaker = //String형의 타입지정하
new FilledListMaker<String>(); //여 인스턴스 생성
List<String> list = stringMaker.create("Hello", 4);
System.out.println(list);
}
}

//Output
// [Hello, Hello, Hello, Hello]


결국 제네릭의 개념은 클래스의 본래 취지(범용적이고 재사용 가능한)를 위해 나온 더욱 보완된 개념이라고 말 할 수 있다. 위의 코드문을 유심히 보면 알겠지만 제너릭은 어떤 추가된 기능이라기 보다는 클래스 작성 표기 방식으로서 표현 된다고 할 수 있다. 타입 파라미터를 이용한 클래스의 작성을 통해 향후에 그 클래스를 사용 할 때 더 명확하고 업캐스팅으로 부터의 에러가 없도록 해주는 장치인 것이다.