자바 제네릭, 와일드카드

OneTwoThree·2023년 4월 1일
0

자바

목록 보기
5/19

제네릭

제네릭 클래스

제네릭 기반의 클래스 정의를 통해 자료형에 의존적이지 않은 클래스 정의를 할 수 있다.

class Box<T>{

    T content;
    public Box(T content){
        this.content = content;
    }

    public void show(){
        System.out.println(content);
    }
}

class Toy{
    int price;
}

public class Main {
    public static void main(String[] args){
        Box<Integer> b1 = new Box<>(1);
        Box<String> b2 = new Box<>("string");
        Box<Toy> b3 = new Box<>(new Toy());
        b1.show();
        b2.show();
        b3.show();
    }
}

T : 타입 매개변수
Toy : 타입 인자
Box<Toy> : 제네릭 타입(매개변수화 타입)

둘 이상의 타입 매개변수로 제네릭 클래스를 정의할 수 있다.
class Box<L,R> 과 같이 ..

타입 인자로 기본 자료형 int 등은 사용 불가능
Wrapper 클래스 Integer를 사용해야 함

제네릭 메소드

반환형 앞에 제네릭임을 표시해준다
public static <T> 반환형 함수명(매개변수,..)
와 같이 선언한다.
public static <T> Box<T> makeBox(T o);
반환형이 Box<T> , 매개변수 T인 메소드이다.
제네릭 메소드는 메소드 호출 시 자로형이 결정된다

제네릭 메소드 호출 시
<String>makeBox("Hello");와 같이 호출한다.
makeBox("Hello"); 와 같이 제네릭 부분을 생략하고 호출하면 인자에 따라 컴파일러가 판단한다.

제네릭 인자 제한

class Box<T extends A>
제네릭 인자 T는 A를 상속하는 클래스형만 올 수 있다.
이렇게 정의하면 T는 A클래스의 메소드를 상속하므로 Box 클래스 내에서 T를 통해 A클래스의 메소드를 사용가능하다.

interface Box<T extends A>
인터페이스에도 적용 가능

class Box<T extends A&B>
하나 이상의 클래스, 인터페이스에도 적용 가능
T는 A를 상속하고 B를 구현해야 함

제네릭 메소드에서도 가능하다.
public static <T extends A> Box<T> makeBox(T o);

와일드카드

와일드카드는 제네릭 메소드를 대신할 수 있는 방법이다.
<?>를 사용해 제네릭 메소드를 선언한다.

//제네릭 메소드 
public static <T> void showBox(Box<T> box);
public static <T> Box<T> createBox();

//와일드카드 
public static void showBox(Box<?> box);
public static Box<?> createBox();

제네릭 메소드는 정해지지 않은 어떤 클래스형을 나타내는데 사용한다.
<T>Integer, Box, Box<String> 등 다양하게 나타낼 수 있다.

반면 와일드카드는 제네릭 타입, 즉 매개변수화 타입을 나타낼 때 사용해야 한다.
public static void test(? value)
위와 같이 사용할 수 없다.
public static void test(Box<?> value)
이렇게 매개변수화 타입을 나타낼 때 사용해야 한다.

와일드카드 상하한 제한

  • 상한 제한
    public 반환형 메소드명(클래스<? extends 슈퍼클래스> 레퍼런스)
    ?에 오는 클래스 타입은 슈퍼클래스 또는 슈퍼클래스를 상속한 클래스여야 함
  • 하한 제한
    public 반환형 메소드명(클래스<? super 서브클래스> 레퍼런스)
    ?에 오는 클래스 타입은 서브클래스의 슈퍼클래스여야 함

0개의 댓글