본문 바로가기

Programinng/Java

자바(Java) - Generic 제너릭

우리가 흔히 Collection에서 Generic을 볼 수 있다. Generic은 구현하는 곳에서 Type을 정하지 않고 사용하는 곳에서 선택하도록 미루는 것이다. 이렇게 하는 이유는 하나의 구현에서(한 번 작성한 class로) 여러개의 Type을 사용하기 위해서이다. 그렇게 하지 않으면 사용할 Type마다 class를 작성해 줘야한다. (String을 받는 List, Integer를 받는 List ...또는 사용자가 정의한 Object는 어쩔텐가..)




List strList = new ArrayList(); 
String temp = (String) strList.get(0);


Generic은 JDK1.5부터 나왔는데, 위의 코드는 Generic을 사용하지 않고 ArrayList를 사용하는 코드이다. ArrayList는 Object를 받고 있으므로 실제  List에서 데이터를 받아올때 개발자가 일일이 Casting을 해줘야만 한다. 그렇지 않을 경우에는 애러를 발생한다. 

한 두줄이야 기꺼이 써주겠지만, 이게 수십 수백 라인이라면 굉장히 까다롭다. 또 Object가 바뀔경우 여기저기 써있는 Casting을 일일이 수정해 줘야 한다. 


이러한 지저분한 Casting의 문제를 해결하기 위해 개발자들은 다음처럼 Wrapping하여 사용하였다. 이렇게 List를 직접 호출하지 않고 따로 정의한 class를 거쳐서 실행한다.


public String get(int index){ 
    return (String)strList.get(index); 
}




하지만, 1.5 부터 Generic이 추가 되면서 다음처럼 쓸 수 있게 됐다.


List<String> strList = new ArrayList<String>(); 
String temp = strList.get(0);


얼마나 간편한가? 이제 일일이 Casting하는 복잡한 코드는 사라졌다. 


List<String> strList = new ArrayList<String>(); 

이렇게 양쪽으로 제너릭을 쓰는것도 복잡하게 느껴진다면 타입추론을 사용하면 된다. 




다음은 ArrayList의 구현 코드이다.

public class ArrayList<E> extends AbstractList<E> 
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable


ArrayList class선언 부에서 이렇게 사용하면 add method에서는 이렇게 구현이 되겠다.

public boolean add(E e) { 

   ... 
}



ArrayList는 AbstractList를 상속 받았으며 List Interface를 Implements하였다. 둘다 Generic을 사용하였으며, 실제 Type은 이것을 구현하는 곳(ArrayList)로 미루었다. 이를 구현하는 ArrayList도 마찬가지로 미루어진 Type을 다음 사용할 곳에 또 다시 미루었다. 그리하여 다음과 같은 코드가 가능 할 수 있는것이다.


List<String> strList = new ArrayList<String>(); 


위의 코드는 다음과 같은 효과를 나타낸다.


public class ArrayList<String> extends AbstractList<String> 
        implements List<String>, RandomAccess, Cloneable, java.io.Serializable 


public boolean add(String e) { 

   ... 
}





Generic에서 <T extends Duck> 같은 것도 있는데, 이건 Duck을 상속받은 class만 들어 올 수 있고 Casting을 Duck으로 해준다. 

public class DuckCoop <T extends Duck>{ 
}


위 처럼 정의하고 아래 처럼 사용한다.


DuckCoop<RedDuck> duckcoop = new DuckCoop<RedDuck>(); 


Duck을 상속받았다면 RedDuck이건 WhiteDuck이건 오리라면 오리장안에 들어 올 수 있다.