하이..
언어공부를 하다보면 한번쯤은 이 Generic에 의문을 가지는데, 오늘 한번 큰 마음 먹고 정리를 해보려고한다.
우리는 다양한 방식으로 Generic을 활용해 오고 있었다.
아래 예제 코드를 보자.
List<Integer> lists = new ArrayList<Integer>();
HashMap<Integer, String> map = new HashMap<Integer, String>();
우리는 개발할 때 <> 괄호안에 들어가는 타입을 따로 정해준다. 만약에 저 리스트나 맵이 별도의 타입을 지원해주는 용도로 각각 만들어져 있다고 생각해보자. 그건 정말 비효율적인 내용이 되지 않을까 생각한다.
ArrayList를 까보면 아래의 그림처럼 되어있는데,
괄호 안에 E 가 있다. E는 보통 Element를 의미한다. 이처럼 제네릭에서는 다양한 타입들을 약속해놓고 사용하는데 그 내용은 아래와 같다.
타입 | 설명 |
<T> | Type |
<E> | Element |
<K> | Key |
<V> | Value |
<N> | Number |
이렇게 제네릭을 쓰면 몇가지 장점이 있는데,
먼저 컴파일 단계에서 잘못된 타입으로 인한 에러를 방지할 수 있고 (물론 컴파일단계에서만 형 안정성을 제공함으로, 런타임 단계에서는 안정성을 보장받지는 못한다.)
클래스 외부에서 타입을 지정해주기 때문에 따로 타입을 체크하거나 캐스팅을 해줄 필요가 없다.
그리고 자료구조를 다양한 비슷한 상황에서 상용하는 것처럼 제네릭을 잘 이용하면 코드의 재 사용성이 높아진다.
1. 클래스 및 인터페이스 사용 방법
public class GenericTestClass <T> {...}
public Interface GenericTestInterface <T> {...}
기본적으로 위처럼 클래스나 인터페이스를 선언하여 제네릭을 활용할 수 있다. 저기서 선언한 T 타입은 각 블럭안에서 유효하게 동작한다.
여기서 실제로 괄호 안에 들어가는 값은 primitive 타입이 아니라 참조 타입인 Integer, Double. Boolean 등의 Wrapper Type 이 와야하고, 사용자가 정의한 클래스 타입도 올수 가 있다.
2. Generic 클래스 생성
실제로 간단하게 제네릭 클래스를 만들어보면 아래와 같다.
class GenericTestClass <E> {
private E element;
void set(E element) {
this.element = element;
}
E get() {
return element;
}
}
class GenericTestClass2<K, V> {
private K key;
private V value;
void set(K key, V value) {
this.key = key;
this.value = value;
}
K getKey() {
return key;
}
V getValue() {
return value;
}
}
public class GenericTest {
public static void main(String[] args){
GenericTestClass<String> object1 = new GenericTestClass<>();
object1.set("a");
System.out.println(object1.get());
GenericTestClass<Integer> object2 = new GenericTestClass<>();
object2.set(1000);
System.out.println(object2.get());
GenericTestClass2<String, Integer> object3 = new GenericTestClass2<>();
object3.set("key",123);
System.out.println("key : " + object3.getKey() +" , value : " + object3.getValue());
}
}
GenericTestClass 는 파라미터를 하나만 보내 제네릭 타입을 지정해주고, GenericTestClass는 두개를 지정해주는 예제이다. 프로그램을 돌려보면 아래의 결과가 나오는 것을 확인할 수 있다.
오늘은 Generic Class 와 InterFace를 생성하고 사용하는 방법을 알아봤다. 다음에는 제네릭 메서드를 사용하는 방법을 포스팅해보도록하겠다.
'Programming > JAVA' 카테고리의 다른 글
[java] Java 에서 Stream 사용하기 (0) | 2021.11.10 |
---|---|
[java] 함수형 인터페이스 (0) | 2021.11.04 |
[Java] Java Exception 처리하기 (0) | 2021.09.15 |
[Java] wait(), notifyAll() 를 활용한 스레드 동작 순서 제어 (2) | 2021.09.09 |
[Java] 객체 정렬하기 (Comparable 인터페이스 이용) (0) | 2021.09.07 |
댓글