자바 1.5에서부터 제너릭 기능이 추가 되었다.
내가 아는 제너릭은 타입 캐스팅의 비용을 줄이고, 런타임시에 발생하는 오류를 줄이며, 가독성이 좋은 코드를 만들기 위해 나온 기술이라고 알고 있다.
또 한 가지 제너릭을 통해 메소드의 return 타입의 제약을 해소하고, 타이트하게 문법을 체크하는 정적 타입 언어의 특성에서 동적 타입 언어와 같은 느슨한 스타일의 언어로 변화되기를 원하는 것 같다.
정적 타입 언어는 IDE툴을 이용하여 컴파일 타임에 문법 체크 및 오류를 사전에 발견할 수 있는 장점이 있다. 그러나 문법의 타이트한 체크로 인해 코드양이 많아진다.
이런 단점을 자바에서는 제너릭을 이용해 해소하고 있다.
동적 언어는 런타임 시에만 문법 오류를 확인할 수 있고, 강력한 개발 도구도 많지 않다.
또한 동적 언어는 리펙토링을 하기에 큰 위험요소가 따른다.
리펙토링이 어렵다는 현실적인 문제가 있으며 이로 인하여 소프트웨어 유지보수는 어려워 질 것이다.
유지보수가 어렵다는 건 아무리 잘 만든 코드라도 시간이 지나면 점점 스파게티 코드로 변해버리고 말 것이고, 우리를 고통스럽게 할 것이다.
파이썬, 스칼라, 자바스크립트 같은 언어들이 동적 타입 언어이다. (맞나?)
아래의 코드와 같이 add 메소드에는 어떤 타입의 파라미터가 전달 되어도 상관 없다.
GenericDAO 객체를 사용하는 클래스에서 사용할 타입을 명시하게 되면 그 타입에 맞는 파라미터를 던져주고, 리턴 받으면 된다.
만약 제너릭이 없었다면 GenericDAO 클래스를 한 개 더 만들거나 메소드를 추가해 줘야 하는 작업이 생긴다.
public class GenericTest {
public static void main(String[] args) {
GenericDAO<Integer> userDAO = new GenericDAO<Integer>();
userDAO.add(111);
GenericDAO<String> userDAO1 = new GenericDAO<String>();
userDAO1.add(“1234”);
}
}
class GenericDAO<T> {
public T add(T param) {
System.out.println(param);
return param;
}
}
이런 변화된 자바를 보면 점점 동적 언어의 장점을 받아들이고, 활용하는 것을 볼 수 있다.
이렇 듯 리턴 타입과 파라미터 타입에 대한 느슨함을 지원해주는 제너릭은 동적 타입 언어의 장점을 받아들이기 위해 탄생된 것이 아닐까?