제네릭(Geceric)의 정의
제네릭(generic)은 데이터 타입을 일반화하는 것. 다시 말해, 특수한 형태의 변수로 존재하다가 변수가 할당될 때 그 타입이 정해지는 것입니다.
조금 더 쉽게 말하자면, 클래스나 메서드 내부에서 사용할 변수의 타입을 외부에서 지정하는 것입니다.
개념만 들어보면 처음 듣는 개념인 것 같지만 사실 다들 한번씩 써본 형태입니다.
List<String> list = new ArrayList<>();
위처럼 List 타입의 변수를 선언할 때 각 요소마다 특정 값을 저장하기 위해서 홑화살괄호(<,>) 안에 String이라고 명시한 부분이 바로 제네릭입니다.
실제로 List 클래스를 들어가 보면 다음과 같은 형태로 되어있는 걸 볼 수 있습니다.
public interface List<E> extends Collection<E>
List<E> 의 형태로 여기서 나온 E는 List 배열의 각 요소를 뜻합니다.
다른 예시를 하나 더 들어보자면 Map을 선언하는 형태를 보겠습니다.
Map<String, Object> map = new HashMap<>();
마찬가지로 Map<String, Object>의 형태로 선언되어 있는데 key값으로는 String을 value 값으로는 Object를 받아오는 것으로 선언하였습니다.
실제로 Map 클래스를 살펴보면 다음과 같습니다.
public interface Map<K, V>
설명한 내용과 똑같이 K, V 값을 받고 있습니다.
그래도 명확하게 풀리지 않는 의문이 있는데, 그래서 E, K, V 가 뭔데? (제네릭이 뭔데?)
제네릭 식별자
제네릭 식별자는 정해진 바 없으며 본인이 사용하고 싶은 대로 사용해도 상관없습니다.
다만, 다음과 같은 사회적 약속은 존재합니다.
기호 | 설명 |
<E> | 배열의 각 요소 (Element) |
<T> | 타입 (Type) |
<K> | 키 (Key) |
<V> | 값 (Value) |
<N> | 숫자 (Number) |
제네릭 사용하기
제네릭을 실제로 사용하기 위한 테스트 코드를 작성해봅시다.
class Test<T>{
private T val;
public T getVal(){
return val;
}
public T setVal(T val){
this.val = val
}
}
Test라는 이름의 클래스가 있고 내부에 getter와 setter가 정의되어 있습니다.
이 클래스에 실제로 값을 할당해주겠습니다.
Test<String> test = new Test<>();
위와 같이 제네릭 타입에 String 타입을 선언하는 순간 Test클래스 내부적으로는 T 타입이 String 타입으로 바인딩됩니다.
그럼 Test 클래스는 아래와 같은 형태를 띠게 되는 겁니다. 다르게 Integer 형태로 선언하게 되면 T 타입이 모두 Integer로 변하게 되는 것이고요.
class Test<String>{
private String val;
public String getVal(){
return val;
}
public String setVal(String val){
this.val = val
}
}
여기서 주의할 점이 있습니다. 이미 한번 특정 타입으로 바인딩된 변수는 다른 타입으로 접근하려 하면 에러가 발생합니다.
List<String> list = new ArrayList<>();
// String 타입의 요소 추가
list.add("test");
// int 타입의 요소 추가 : 에러 발생!!!!
list.add(10)
제네릭 사용하기 : 인터페이스
제네릭을 인터페이스에도 사용 가능합니다. 다만, 실제로 구현부 클래스 및 메서드에도 인터페이스의 제네릭 타입과 맞추어서 사용합니다.
interface TestInterface<T>{
public void setValue(T t);
public T getValue();
}
class TestClass<T> TestClass implements TestInterface<T>{
private T value;
@Override
public void setValue(T t){
value = t;
}
@Override
public T getValue(){
return value;
}
}
이러한 인터페이스를 아주 잘 활용하고 있는 부분이 바로 람다식(lambda)인데 이 내용은 추후 알아보도록 하겠습니다.
잘못되었거나, 이해가 되지 않는 부분은 댓글 남겨주세요. 감사합니다.
'개발 > 웹 개발' 카테고리의 다른 글
[JAVA/자바] 옵셔널(Optional) (0) | 2024.08.30 |
---|---|
[JAVA/자바] 람다(Lambda) (6) | 2024.04.03 |
[JAVA/자바]HttpURLConnection 이용한 파일 다운로드 (0) | 2023.02.08 |