Java

Generic

jamie. 2020. 1. 7. 21:11
반응형

Generic이란?

타입 형 변환에서 발생할 수 있는 문제점(런타임)을 컴파일시 점검할 수 있도록 하기 위해 만들어짐

즉, 명시적으로 타입을 지정할 때 사용하는 것

<>안에 명시를 해주면 됨

Generic Type - Java Default Rule

지키지 않아도 컴파일은 가능

다른 사람이 보더라도 쉽게 이해 할 수 있도록

  • E : 요소 (Element)

  • K : 키

  • N : 숫자

  • T : 타입

  • V : 값

  • S, U, V : 두 번째, 세 번째, 네 번째에 선언된 타입

Generic의 Wildcard <?>

어떤 객체를 Wildcard로 선언하고, 그 객체의 값은 가져올 수 있음

Wildcard 객체에 제네릭 타입으로 값을 지정하는 것은 불가능

// 이렇게 선언하면 여러 가지 종류의 매개변수를 다 받을 수 있음
public void jamieWildcardMethod(jamieWildcardGeneric<?> c) {
    Object value = c.toString(); // 예시
}

// 이렇게 선언하면 에러남 - 알 수 없는 객체에 타입을 지정할 수 없기 때문
public void jamieCallWildcardMethod() {
    jamieWildcardGeneric<?> wildcard = new jamieWildcardGeneric<String>();
}

// 에러는 대충 cannot be applied to(java.lang.String) ...(생략)

매개변수를 <?>로 선언하면, 타입에 한정적이지 않도록 매개변수들을 받을 수 있음

대신, 메서드 내부에서 해당 타입을 모르기 때문에 Object로 변수를 선언하여 처리해야만 함

타입의 종류가 정해져있다면, instanceof 를 사용하여 해당 타입을 확인하며 됨

Bounded Wildcards <? extends 타입>

Wildcard로 사용하는 타입을 extends 타입을 붙여 범위를 제한할 수 있음

제네릭 타입으로 지정한 타입을 상속받은 모든 클래스를 사용할 수 있다는 의미

다른 타입을 제네릭 타입으로 선언한 객체는 컴파일시 에러 발생

마찬가지로 값은 할당할 수 없음 (매개변수용)

메서드를 제네릭하게 선언하기

Wildcard로 메서드를 선언시, 선언된 객체에 값을 추가할 수 없음

→ 그렇다면 어떤 방법을 사용해야 할까?

 

메서드 선언시 리턴 타입 앞에 제네릭한 타입을 선언해주고, 그 타입을 매개 변수에서 사용

 컴파일할 때 문제 없이 사용 가능, 값도 할당 가능

// 메서드를 제네릭하게
public <T> void jamieGenericMethod(jamieWildcardGeneric<?> c, T addValue) {
    c.setWildcard(addValue);
    T value = c.getWildcard();
}

// Bounded Wildcards처럼 extends 사용할 수 있음
public <T extends 타입> void jamieBoundedGenericMethod(jamieWildcardGeneric<?> c, T addValue) {
}

// 제네릭 타입 여려개 사용 가능, 콤마(,)로 구분
public <S, T extends 타입> void jamieMultiGenericMethod(jamieWildcardGeneric<?> c, T addValue, S another) {
}

 

반응형