╱╱╭╮╱╱╱╱╱╱╭━━━╮╱╱╱╭╮╱╭╮╱╱╱╱╱╱ ╱╱┃┃╱╱╱╱╱╱┃╭━╮┃╱╱╱┃┃╱┃┃╱╱╱╱╱╱ ╱╱┃┣━━┳━━╮┃┃╱┃┣━╮╱┃╰━╯┣━━┳━╮╱ ╭╮┃┃╭╮┃┃━┫┃╰━╯┃╭╮╮┃╭━╮┃╭╮┃╭╮╮ ┃╰╯┃╭╮┃┃━┫┃╭━╮┃┃┃┃┃┃╱┃┃╭╮┃┃┃┃ ╰━━┻╯╰┻━━╯╰╯╱╰┻╯╰╯╰╯╱╰┻╯╰┻╯╰╯

Java/Java 기초

[Java] 제네릭 (Generic)

재안안 2022. 4. 21. 04:36

이번에는 제네릭(Generic)에 대해서 알아보겠다.

 

우선 generic이란 '일반적인'이라는 뜻이다.

단어의 뜻을 알고 자바에서 Generic이 뜻하는 것을 접근하면 이해가 훨씬 쉽다.

 

Generic을 한마디로 표현하자면  '일반화된 Class 자료형'이다. (Generalized Class type)

 

Class가 일반화된다는게 무슨소리인가? 라고 생각할 수도 있다.

 

그래도 자료형을 기억하자. 아래에서 예제를 통해 설명하겠다.

 

 

자바에서 Generic은 아래와 같다.

 

GenericEx 정의

 

  • Class가 정의되었다.
  • Class 이름이 조금 이상하다.
  • data의 자료형도 이상하다.
  • setter와 getter가 정의되었다.

 

여기서 Generic은 T이다.

 

Generics<T>의 필드에서 "T date;" 가 실행되었다.  분명 자료형이 명시되어야 하는데 T가 적혀있다.

그러나 이때 T를 자료형(data type)으로만 생각하지 말고 Class로 봐야한다.

 

코드를 해석하자면 아래와 같다.

 

 

  • Class 이름은 GenericEx이고 Generic T를 외부에서 입력받을 것이다.
  • Generic Class의 data는 private이고 T의 자료형(Class)을 가질 것 이다.
  • setData는 외부에서 입력받는 data를 this.data에 대입할 것이다.
  • getData는 this.data를 반환할 것이다.

 

Generic을 포함하는 Class를 Generic Class라고 한다.

 

이제 Generic을 사용해보겠다.

 

아래의 예제를 보면 바로 이해가 갈 것이다.

 

main 클래스
실행 결과

 

 

이처럼 T는 사용자가 필요에 따라 외부에서 지정할 수 있다. 

실제로 T는 main 클래스에서 Generic Class가 생성(인스턴스화)될 때 지정되었다.

 

GenericEx<Integer>가 생성될 때 GenericEx의 내부에서는 T가 Integer로 교체된다.

혹시 이해가 안된다면 T를 매개변수로 생각해보아도 좋다.

 

  • Generic 사용시 주의사항

 

Generic 사용시 주의사항으로 T는 항상 Class 자료형이여야한다.

 

실제로 예제에서도 T를 지정할 때 int대신 Integer로 명시하였다. String은 원래 Class이다.

이처럼 data type으로 지정할 수도 있지만 Class 자료형으로도 많이 지정한다.

 

아래와 같이 사용할 수도 있다.

 

GenericEx<Predator> ge = new GenericEx<Predator> (이전 포스트들에서 많이 썼던 클래스)

 

이처럼 T는 data type으로 국한되는게 아니라 모든 Class 자료형으로 지정이 가능하다.

 

Generic은 모든 Class 자료형을 지정할 수 있다.

이때 Generic은 꼭 문자 T를 써야하는 것은 아니다. 어떤 문자는 괜찮다. 심지어 여러개를 써도 괜찮다.

 

  • Generic 표준 문자

 

그런데 보통 지정하고자하는 Class 자료형에 따라 Generic의 문자를 구분하여 사용한다.

 

아래의 정리를 통해 이를 준수하는 것이 좋겠다.

 

문자 지칭
T Type
E Element
K Value
V Key
N Number

 

  • Generic Wild Card

 

마지막으로 Generic Wild Card라는 것이 있다.

 

Wild Card는 스포츠 용어로 와일드카드는 스포츠 경기 대회에서 정원 외 참가자를 뜻한다.

자바에서도 비슷한 느낌으로 사용된다. 조커픽같다.

 

Wild Card는 문자로 "?"를 사용한다.

 

  • GenericEx<?> : 어떤 클래스인지 지정x

 

GenericEx 클래스에서 정의
main 클래스에서 실행
실행 결과

 

  • ge.print(ge2)는 1을 출력하였다.
  • ge2.print(ge)는 hi를 출력하였다.
  • 이처럼 인자로 들어오는 데이터의 자료형에 의하여 알 수 없을 때 <?>를 사용한다.

 

Generic은 외부에서 Class자료형이 지정된다.

 

<?>는 내부에서 아직 지정되지 않았지만 외부에서 어떠한 Class 자료형이 오더라도 실행하고 싶을 때 사용한다.

 

또는 Wild Card는 메소드 반환값의 자료형이 계산에 따라 바뀔 때 사용한다.

 

  • Generic에 들어가는 Class들에 대한 범위지정

 

Generic에 들어갈 수 있는 Class 자료형의 범위가 너무 광범위할 때 범위를 제한할 수도 있다.

 

Generic Class를 정의할 때 아래와 같이 해주면 된다.

 

  • GenericEx<? extends A> : ?는 A와 A의 자식 클래스들만 지정 가능
  • GenericEx<? super B> : ?는 B와 B의 부모 클래스들만 지정 가능