제네릭(Generic)이란?
List<String> list1 = new ArrayList<>();
Map<String, Object> map = new HashMap<String, Object>();
위의 List<String> 과 같이 "<>" 꺽쇠 안의 클래스 타입이 명시되어 있는 것을 확인할 수 있다.
이러한 "<String>" 꺽쇠 안에 데이터 타입을 컴파일 시에 미리 지정하는것을 제네릭이라고 한다.
제네릭은 클래스나 메서드에서 사용할 내부 데이터 타입을 컴파일 시에 미리 지정하여 타입검사를 할 수 있다.
- 클래스나 메서드 내부에서 사용되는 객체 타입의 유연성과 안정성을 확보한다.
- 런타임 시 발생할 수 있는 타입 에러를 컴파일 전에 검출하여 안정성을 확보한다.
아래 예시를 확인해보자
List<String> list = new ArrayList<String>();
list.add("obo");
// type error
Integer i = (Integer)list.get(0);
위 String 형 List 에 "obo" 라는 String 값을 넣고 .get(0) 을 통해 0번째의 값을 Integer 로
형변환 시 런타임 오류가 나타난다.
이러한 런타임 에러를 사전에 방지하고자 제네릭을 사용하여 컴파일 시에 나타나는 에러를 잡는다.
class SampleTest<T>{
// 데이터 타입 T
private T data;
// 파라미터로 T(Type) 를 설정
public void setData(T d){
this.data = d;
}
// data 를 리턴
public T getData(){
return data;
}
}
위; SampleTest 클래스는 제네릭을 이용하여 클래스 선언 시 T 인 Type 을 선언했다.
T 는 타입 변수라고 하며, 임의의 참조형 타입을 의미한다.
위 제네릭 클래스를 생성할 때는 사용할 타입 변수를 명시하여 생성하면 된다.
// 클래스 선언과 동시 타입 변수(T) 자리에 String 형태의 타입 변수를 명시하여 생성
SampleTest<String> test = new SampleTest<String>();
// String 문자열을 setData 메서드를 통해 설정
test.setData("안녕하세요");
system.out.println("String 형태 : "+test.getData());
//결과
String 형태 : 안녕하세요
위는 SampleTest<String> 으로 제네릭 클래스의 타입변수 자리에 String 형태를 명시하여 생성하였다.
생성 후 setData 메서드를 통해 "안녕하세요" 문자열로 설정했고 getData() 로 호출하여 결과값을 확인하였다.
이렇게 제네릭 클래스는 타입 변수를 미리 지정하여 런타임 시가 아닌 컴파일할 때 에러를 찾을 수 있다.