MapleStory Cookie With Halo

☕ JAVA/☕ Variables & Data Type

[JAVA]Generic<T> & Wild card<?>

뉴이 NUEY 2024. 9. 30. 16:37
반응형

Collection(Map/Set/List)에서의 Generic

 

<Type>
: 개발자가 Type을 지정한다.

 

제네릭을 지정하지 않으면 Collection에 아무 타입의 값을 넣을 수 있습니다.

 

제네릭을 <String>으로 지정한 순간부터 String타입만 담을 수 있습니다.

 

Map에서는 Key와 Value의 타입 두가지를 지정합니다.

 


 

장점

 

 

  • 제네릭이 없는 List에 여러가지 타입의 값을 담았을 경우,
    int hello = (int) lst1.get(0);
    와 같이 형변환시에 ClassCastException이 일어납니다.

  • 제네릭을 이용해 하나의 타입으로 지정하면 컴파일 시, 지정한 제네릭을 사용하는 지 Type검사를 합니다.

  • 제네릭을 Collection(Map/Set/List)에 사용하면, 지정한 Type만을 사용할 수 있지만

  • 오류방지와 사용에 수월합니다.
    만약 제네릭을 사용하지 않을 시 Collection사용 시 값의 타입이 무엇인지 확인 후 사용해야 하겠죠.
    또한 제네릭을 보고 어떤 타입을 사용하고 있는 지 바로 확인 할 수 있습니다.

 


 

제네릭을 지정하지 않으면 (String)과 같이 형변환을 적어주어야 하지만

 

제네릭이 지정되어 있으면 형변환이 불필요합니다.

 


Class & Method 에서의 Generic. 타입변수. 

위에서 제네릭은 Collection(Map/Set/List)에서 사용하는 방법이었습니다.
Collection에서는 제네릭은 하나의 타입만 지정해서 사용할 수 있지만

Class와 Method에서는 제네릭은 거의 반대로 사용됩니다.
사용법도 좀 다릅니다.

 


 

<T>

 

한 눈에 보기에도 다르죠?

 

  • 여기에서 T는 타입을 지정한 게 아니라 개발자가 지정한 타입명입니다.

  • 변수 a를 선언할 때
    private T a;
     와 같이 타입명 대신 사용할 수 있습니다.

 

안 좋은 예시

 

  • 이렇게 아무 이름이나 지정할 수 있지만 <T>로 사용하기로 암묵적 약속이 되어있습니다.

  • T : Type 의 약자.

 


 

사용법
: 모든 타입 허용

 

 

출력결과

 

  • T 라는타입은 마치 Object와 같이 모든 타입을 허용합니다.
    → 따라서 int/boolean/String/Collections와 대신 적어 사용할 수 있습니다.

  • 호출한 사용자가 지정한 타입으로 사용가능합니다.

클래스에서 <T>를 지정하지 않아도, 메서드 에서만 지정해 사용할 수 있습니다.

 


 

주의할 점
Generic은 Collection에서 사용 시 타입은 좁히는 역할을 하고
Class & Method에서는 타입을 넓히는 역할을 합니다.

그럼 무조건 유연성을 높이게끔 <T>를 사용하는 게 나을 것 같지만 그렇지 않습니다.
상위 객체에서 사용시에는 유연성이 높게 <T>를 사용할 수 있지만
하위 객체에서는 범위가 좁고 명확해야만 합니다.

따라서 하위 class & method에서는 <T>사용이 좋지 않습니다.

 


 

제한된 generic
<subClass extends superClass>

 

T를 사용할 수 있는 타입으로 Number클래스로 지정하면,

 

Number클래스를 상속받는 하위 클래스들만 사용할 수 있다.

 

위의 주의할 점에서 말했듯이 타입의 범위는 좁을 수록 좋습니다.
하지만 하위 클래스임에도 불구하고 어쩔 수 없이 타입을 넓혀야 한다면, 이렇게 제한된 제네릭을 사용하면 됩니다.

 


 

제약사항

 

  • 타입 변수 대입은 인스턴스 별로 다르게 가능하기에, static 멤버에는 사용불가다.
  • 기본배열로는 사용가능하지만, 인스턴스 생성자 new에는 사용불가.


 

generic 형변환

 

 

  • generic타입과 원시 타입간의 형변환은 바람직하지 않다.(가능은 하지만 경고 발생)

  • 정확히는 제네릭<T>를 사용하는 클래스를 원시타입으로 선언하지 않는 것이 좋다.

  • 다시 말해 제네릭이 있는 클래스는 제네릭을 사용하는 것이 옳다.


 

 

  • 서로 다른 타입의 generic은 형변환이 안된다.

  • 와일드 카드를 사용한 형변환은 가능하다.


Wild card <?>

 

Wild card
 <?
: 하나의 참조변수로 여러 타입을 대입할 수 있게한다.

 

 

<? extends T> 상한 제한. T와 그 자손들만 참조가능. 가장 많이 사용됨.
<? super T> 하한 제한. T와 그 조상들만 참조가능.
<?> 제한 없음. 모든 타입 가능. <? extends Object>와 동일.

 

❗ 와일드 카드는 클래스 생성시에는 사용 불가입니다.
불가능.
위의 예제처럼 변수나 메서드에서 사용가능합니다.

 


 

generic과 wild card 차이점

 

  • 제네릭은 타입을 지정하여 사용범위를 좁히는 용도입니다.

  • 와일드 카드는 호출할 때 여러 타입을 사용할 수 있게 사용범위를 넓히는 용도입니다.


참조영상

반응형