[Java] 제네릭(Generic)
제네릭(Generic)
클래스나 메서드를 선언할 때 데이터 타입을 미리 정하지 않고, 객체를 생성할 때나 메서드를 호출할 때 구체적인 타입을 지정하는 것을 말한다. 설계 시 구체적인 타입을 언급하지 않고 포괄적인 타입으로 작성함으로써 코드의 재사용성을 높이고, 컴파일 시 타입 안정성을 보장한다.
🔻아래의 예시를 보며 이해를 해보자.
Box에 넣을 내용물로 content 필드를 선언하려고 할 때, 타입을 무엇으로 해야 할까?🤔
public class Box {
public ? content;
}
다양한 내용물을 저장해야 하므로 특정 클래스 타입으로 선언할 수 없다. 그래서 다음과 같이 Object 타입으로 선언한다.
public class Box {
public Object content;
}
Object 타입은 모든 클래스의 최상위 부모 클래스이다. 그렇기 때문에 객체는 부모 타입인 Object로 자동 타입 변환이 되므로 content 필드에는 어떤 객체든 대입이 가능하다.
Box box = new Box();
box.content = 모든 객체;
❗하지만 Box 안의 내용물을 얻을 때 문제가 발생한다. content는 어떤 객체가 대입되어 있는지 확실하지 않기 때문이다.
내용물의 타입을 안다면 강제 타입 변환을 거쳐 얻을 수 있다. 그러나 어떤 내용물이 저장되어 있는지 모른다면 변환하기 어렵다. 따라서 Object 타입으로 content 필드를 선언하는 것은 좋은 방법이 아니다.
Box를 생성하기 전에 우리는 어떤 내용물을 넣을지 이미 알고 있다. 따라서 Box를 생성할 때 저장할 내용물의 타입을 미리 알려주면 읽을 때 어떤 타입으로 제공할지 알 수 있다. 이것이 제네릭이다.
제네릭(Generic)이란 결정되지 않은 타입을 파라미터로 처리하고
실제 사용할 때 파라미터를 구체적인 타입으로 대체시키는 기능
🔻제네릭 사용 예시
Box 클래스에서 결정되지 않은 content 타입을 T라는 타입 파라미터로 정의
public class Box <T> {
public T content;
}
<T>는 타입 파라미터임을 뜻하는 기호로, 타입이 필요한 자리에 T를 사용할 수 있음을 알려주는 역할
Box의 내용물로 String을 저장하고 싶다면 아래와 같이 Box를 생성할 때 타입 파라미터 T 대신 String으로 대체하면 된다.
Box<String> box = new Box<String>();
box.content = "안녕하세요.";
String content = box.content; // 강제 타입 변환이 필요 없음
Box의 내용물로 숫자 100을 저장하고 싶다면 아래와 같이 Box를 생성할 때 타입 파라미터 T 대신 Integer로 대체하면 된다.
Box<Integer> box = new Box<Integer>();
box.content = 100;
int content = box.content; // 강제 타입 변환이 필요 없음
✨👩💻 ✨
사실 T는 단지 이름일 뿐이기 때문에 T 대신 A부터 Z까지 어떤 알파벳을 사용해도 괜찮다. 다만, 타입 파라미터를 대체하는 타입은 클래스 및 인터페이스라는 것이다.
출처