본문 바로가기
JAVA

java generic 사용법

by 아이티.파머 2021. 6. 1.
반응형

java generic 이란?

java 5 버전부터 등장하기 시작한 제네릭 <> 기능이다. 형변환을 안전하게 해주고, 컴파일시에도 잘못된 형변환을 알려준다. 이로인해 코드의 재사용성을 높일수 있고 , 제네릭 메소드 이용시 타입 세이프 하게 개발가능 하다.

가장 보편하게 알려진 제네릭의 의미는 다음과 같다.

  • 제네릭 은 클래스 내부에서 사용할 테이터 타입을 외부에서 지정하는 기법을 말한다.
  • 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입체크를 해주는 기능이다.

위와 같이 다양한 타입의 객체들을 형변환시, 컴파일시에 도움을 받도록 한다. 제네릭은 사용시 메소드, 클레스, 변수에 활용방법에 따라 명칭이 각기 다르다. 해당 타입종류를 모른다고 해서 문제되진 않는다. Java 개발을 하며 무의식 적으로 다들 사용해보거나 보았던 내용들을 구분 지은것 뿐이다.

모두다 알아볼순 없음으로 여기서는 바운드타입 매겨변수와일드카드서브타이핑, 바운드 와일드 카드타입, 제네릭 메소드 타입 종류에 대해서만 예를 들어 설명하겠다.

제네릭 타입 종류

  • 매캐변수화 타입
  • 언바운드 와일드 카드 타입
  • 바운드 타입 매개변수
  • 재귀적 타입 바운드
  • 제네릭의 서브 타이핑
  • 와일드카드 서브 타이핑 ... <? extends .. > <?
  • 바운드 와일드카드타입
  • 제니릭 멕소드

한정적 타입 매개변수 (Bounded Type Parameter) 란 ?

→ Generic 사용시 타입 파라미터의 범위를 한정적으로 제한할 수 있다.

  • T super Object
  • → 자기 자신과 부모 객체만 사용 가능
  • T extends Object
  • → 자기 자신과 자식 객체만 사용가능

T extends

  • type parameter 의 서브클레스만 타입으로 가져갈때 사용한다.

the below example)

public class GenericTest {

    public static void main(String[] args) {
        GenericTest.extendsTest(0.1);

        // Extends 상위 타입은 에러 Error > 자기 자신과 ,자식 객체만 사용.
        GenericTest.extendsTestCase2(new Circle());
        GenericTest.extendsTestCase2(new ShapesGeneric());
        GenericTest.extendsTestCase3(new Circle());
        GenericTest.extendsTestCase3(new ShapesGeneric());

    }


    public static  <T extends Number> void extendsTest(T data){
        System.out.println(data);
    }

    public static  <T extends Original> void extendsTestCase2(T data){
        System.out.println(data);
    }

    public static  <T extends Original> void extendsTestCase3(T data){
        System.out.println(data);
    }

}

abstract class Original{
    String name;
}

class ShapesGeneric extends Original{
    String superClass;
}

class Circle extends ShapesGeneric {
  String circleSpecial;
}

T super

→ type parameter 의 상위 클래스만 타입으로 사용 할 경우

the below example )

public class GenericTest {

    public static void main(String[] args) {

        //  하위 클레스 타입은 에러 > 자기 자신과 상위 객체만 허용
        //GenericTest.superTestCase3(new ArrayList<Circle>()); -> error
        GenericTest.superTestCase3(new ArrayList<ShapesGeneric>());
        GenericTest.superTestCase3(new ArrayList<Original>());

        GenericTest.superTestCase4(new ArrayList<ShapesGeneric>());
        GenericTest.superTestCase4(new ArrayList<Circle>());
        GenericTest.superTestCase4(new ArrayList<Original>());

    }


    public static  void superTestCase3(List<? super ShapesGeneric> data){
        System.out.println(data);
    }

    public static  void superTestCase4(List<? super Circle> data){
        System.out.println(data);
    }

}

abstract class Original{
    String name;
}

class ShapesGeneric extends Original{
    String superClass;
}

class Circle extends ShapesGeneric {
  String circleSpecial;
}

그럼 언제 extends 와 super 를 사용하면 될까 ?

오라클에서는 PECS(Producer Extends, Consumer Super) 개념으로 가이드 하고 있다.

< In,Out >

  • In 의 경우 extends 를, Out의 경우엔 Super를 사용 하라고 한다.

바운드와 와일드 카드 타입

무공변(invariant)
-
오로지 자기 타입만 허용하는 것
공변 (covariant)
-
구체적인 방향으로 타입 변환을 허용하는 것 (자기 자신과 자식 객체만 허용) <? extends T>
반공변 (contravariant)
-
추상적인 방향으로의 타입 변환을 허용하는 것(자기 자신과 부모 객체만 허용) <? super T>

참고

Difference between and in Java

 

Difference between and in Java

What is the difference between List and List ? I used to use List, but it does not allow me to add elements to it list.add(e), whereas the Li...

stackoverflow.com

 

반응형