2011년 6월 18일 토요일

자바의 제네릭(Generics)


자바의 신기술(?)인 제네릭 타입(Generic Types)에 대해서 공부하는 시간을 가져보겠다. 자바5부터 이것저것 달라지고 추가되는 점이 꽤 있어 새로 자바를 공부하는 이들은 그런게 있나보다하고 그냥 받아들이면 되겠지만 잠시 이 세계를 떠났던 이들(?)은 이게 자바인지조차 혼란스러울 것이다. 특히 오늘 공부할 단원인 제네릭 개념은 특히 더하리라 생각된다. 그러나 걱정할 필요없다. 그동안 자바의 제네릭 때문에 잠시 멀리 떠난 이들은 오늘부로 컴백(?)해주기 바란다.ㅎㅎ 필자가 아주 쉬운 설명과 예제로 여러분의 시름을 덜어줄 것이니까 말이다.^^

자바의 제네릭이라함은 처음에 데이터 자료형인 String이나 Integer같은 형태를 처음에 정해놓지 않고 임의의 타입으로 명시해준 후에 나중에 우리가 직접적으로 해당구문을 사용할때 지정하여 사용하는 형태를 말한다. 어떻게 쓰는지 아래를 보면서 뭐가 다른지 살펴보기로 하자.

class Test64
{
String a;
..
...
}

위의 예제는 클래스에 String 타입의 변수 t를 선언한 것이다.

class Test64 <T>
{
T a;
..
...
}

위의 예제는 제네릭 클래스라고 하는데 임의의 타입인 <T>를 이용하였는데(Type의 약자인 T가 보편적인 제네릭 변수로 쓰인다.) 데이터 자료형이 나중에 String이 될수 있고 Integer나 Double 같은 그 외 다른 데이터 자료형으로 쓰일수도 있다. 즉 처음에 어떤 타입인지 지정하지 않고 나중에 여러분이 사용할때 확정짓는 방식을 말한다. 쓰는 방법은 위와같이 클래스 옆에 제네릭 타입을 선언하고 데이터 자료형이 쓰일 자리에 제네릭 타입인 T를 위와같이 써주면 된다. 한마디로 String이나 Integer가 들어갈 자리에 T를 넣어 쓰고 나중에 String이나 Integer를 정해주면 되는 것이다.

class 클래스명 <제네릭타입>
{
..
...
}

제네릭 클래스를 사용하려면 객체 생성을 할때 제네릭타입이 무엇인지를 정해주어야 한다.

Test64 <String> ts=new Test64 <String> ("클래스 객체 ts 생성");

이렇게 하면 위의 T라고 임의로 적어놓았던 타입이 모두 String으로 바꿔서 쓸수있다고 생각하면 된다.

Test64 ts=new Test64("클래스 객체 ts 생성");

위의 구문이 일반적으로 우리가 객체생성을 할때 쓰는 표현인데 클래스뒤에 제네릭 타입을 써주기만 하면 다를게 없다. 제네릭 타입의 위치를 주의깊게 보고 어떻게 쓰이는지만 알면 크게 어려움이 없을 것이다. 그래도 잘 모르겠다고 탄식하지는 말자.ㅎㅎ 아래의 예제를 보면서 실행을 해보면 저절로 이해가 될것이다.^^


예제를 보면서 제네릭 클래스를 어떻게 구현하였는지 살펴보기 바란다. 예제를 보면 알겠지만 제네릭 클래스의 강력한 기능이 무엇인지 이제 파악이 되는가? 만약 자료형을 초반에 지정해 놓았다치면 String이 되었든 Integer가 되었든 한 타입으로밖에 프로그램을 구현할수 없었을 것이다. 다른 자료형을 쓰려면 그만큼의 코딩을 더해야 하고 프로그램이 더욱 방대해질수 밖에 없는데 이렇게 제네릭 타입을 사용하면 자료형을 원할때 골라 쓸수 있으므로 한결 프로그램이 간결해질수 있다.^^ 예제는 풍부한 주석을 달아놓았으므로 그냥 보면 이해될 것이다. 더이상 필자가 해줄것이 없다.ㅎㅎ

와일드카드라 불리는 <?> 제네릭 타입을 아직 설명안했는데 ?라는 뜻은 간단히 아무 자료형이나 가능하다는 것을 뜻한다. 그래서 아무거나 넣어도 다 작동하는 것이다. 그리고 ?와 함께 상속키워드인 extends나 super를 사용하는 방법이 있는데 하위클래스들이 제네릭타입으로 오느냐 아니면 상위클래스들이 제네릭타입으로 오느냐의 차이이다. 이것도 예제를 이리저리 돌리다보면 크게 무리가 없이 알게될 것이다. 쓰는 방법은 아래와 같다.

<? extends 객체자료형>
<? super 객체자료형>

상속의 개념이 제네릭에 녹아있으므로 아래의 상하위 구조도를 보면 이해하기가 더 쉬울 것이다.^^


예제에서 이용한 Number가 위의 그림처럼 Integer의 (직)상위 클래스임을 상기하면서 예제를  살펴보면 이해하는데 무리가 없을  것이다. 제네릭 타입은 클래스나 인터페이스 그리고 메소드에서도 사용이 가능한데 클래스나 인터페이스는 그 나물에 그 밥이니 이번엔 메소드에서 제네릭 타입이 어떤 식으로 쓰이는지 살펴보기로 하자.


메소드에서 제네릭 타입을 쓰려면 위의 예제처럼 리턴값의 위치 앞에다가 제네릭 타입을 선언한후 자료형이 들어가는 위치에다가 위와같이 쓰면 된다. 제네릭 메소드에서는 자료형을 제네릭 클래스처럼 나중에 특별히 정하지 않아도 자동적으로 자바에서 자료형에 맞게 알아서 처리해준다. 예제에서처럼 역시 메소드에서도 제네릭 타입의 위력(?)을 여지없이 느낄수 있다. 생각해보라. 만약 위의 get( ) 메소드에 제네릭 타입을 쓰지 않고 메인메소드의 명령들을 실행하려면 자료형 타입별로 메소드를 다 따로 만들어야 했을 것인데 제네릭 메소드를 씀으로 인해서 코드가 위와같이 아주 간결해지는 것을 확인할수 있다.^^

그렇게 어렵게 느껴왔던 제네릭이 고작 이거였어? 라고 말하는 이가 상당수 있을 것이다. 자바7에서는 제네릭 타입이 다이아몬드(<>)처럼 빛나게 업그레이드되니 방심하지 말자.ㅎㅎ 제네릭 타입은 코드를 간결하게 만들고 여러분이 초반에 프로그래밍할시 자료형을 통일하거나 확정짓기 힘든 상황에 쓰면 아주 강력한 성능(?)을 발휘한다. 자바에서 새롭게 도입되고 달라지는 개념들이 버젼업이 될때마다 계속해서 나올 것인데 그럴때마다 체념하고 두려워하기 보다는 얼마나 예전보다 프로그래밍하기가 더 편해질까라는 관점으로 접근하는 자세를 가지면 마음도 편하고 여러분의 프로그래밍에 대한 자신감과 실력도 한층더 월등해질 것이라 믿는다.^^

댓글 12개:

  1. 잘보고 갑니다 헷갈렸는데 이해됐네요

    답글삭제
  2. ad가 많아서 불편하긴 하지만 잘보고 갑니다~

    답글삭제
  3. 이해하는데 많은 도움이 되었습니다

    감사합니다

    답글삭제
  4. 좋은내용 정말 감사합니다.

    이렇게 좋은 블로그가 있지만, 블로그에 렉이 너무 심합니다.

    블로그 개선이 필요할듯싶습니다.

    답글삭제
  5. 작성자가 댓글을 삭제했습니다.

    답글삭제
  6. 인간적으로 블로그에 광고가 너무너무 많네요... 하지만 강좌는 잘 봤습니다.

    답글삭제
  7. 쉽게 이해 됬습니다 감사합니다

    답글삭제
  8. 잘봤씁니다. 감사합니다. ~

    답글삭제
  9. 완벽합니다.. 블로그 구독신청합니다^^

    답글삭제