자바 part.5 문제풀이 - 제네릭(Generic) 개념 활용
예제
class Sample<T>{
//Field
private T obj;
//Constructor
Sample(T x){
this.obj = x;
}
//Method
T getObj() {
return obj;
}
void printlnfo() {
System.out.println(obj.getClass().getName());
}
}
public class Collection_Generic03 {
public static void main(String[] args) {
//[1] : 객체 생성 - String
Sample<String> s1 = new Sample<String>("안녕하세요");
s1.printlnfo();
System.out.println(s1.getObj());
//[2] : 객체 생성 - Integer
Sample<Integer> s2 = new Sample<Integer>(100);
s2.printlnfo();
System.out.println(s2.getObj());
//[3] : 형변환 없이 사용
System.out.println(s1.getObj().length());
System.out.println(s2.getObj() + 100);
}
}
1. 제네릭 개념
제네릭은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다. 클래스 또는 메서드에서 사용할 내부 데이터타입을 컴파일 시점에서 미리 명시함으로써, 타입 안정성을 보장하고 형변환 번거로움을 줄인다. 이를 통해 코드의 재사용성이 높아지고, 컴파일 시 타입 체크를 해줘서 오류를 미리 잡아내는 장점이 있다.
예제 코드에서, Sample 클래스는 T 타입의 객체를 저장하고 이를 반환하는 메서드를 가지고 있다. T는 호출하는 곳에서 정의하게 되며, 이를 통해 다양한 데이터 타입에 대응하는 클래스를 하나만 정의하여 사용할 수 있게 된다.
2. 제네릭의 필요성
제네릭을 사용하지 않을 경우, 다양한 데이터 타입을 다루기 위해 다양한 클래스를 생성해야 하거나, 클래스 내에서 데이터 타입에 따른 분기 처리를 해야 한다. 또한 데이터 타입이 Object로 통일되면 데이터를 불러올 때 매번 형변환을 해줘야 하는 번거로움이 있다. 이런 문제를 제네릭을 사용하면 해결할 수 있다.
3. 제네릭의 사용법
제네릭을 사용하는 방법은 간단하다. 클래스나 메서드 선언부에서 "<>" 안에 데이터 타입을 명시하고, 이후 이 데이터 타입을 필요한 곳에 사용하면 된다.
Sample<String> s1 = new Sample<String>("안녕하세요");
위 코드에서, Sample 클래스는 String 타입의 객체를 필요로 한다. 따라서 Sample<String>처럼 타입을 명시하고 생성자에 String 객체를 전달한다. 이를 통해 s1 객체는 내부적으로 String 타입의 객체를 다루게 된다.
주의점
제네릭 타입에는 기본 타입(primitive type)을 사용할 수 없다. 따라서 int, char, double 등의 기본 타입 대신 integer, Character, Double 등의 Wrapper 클래스를 사용해야 한다. 또한, 제네릭 타입은 컴파일 시점에만 필요하며 실행 시점에는 제거되는 Type Erasure라는 과정을 거친다.