Java/java

java :) Generic 정말 끝내자..? Generic class / Generic method

euncheol kim 2022. 5. 17. 11:32

 

 

goal

java의 generic에 대해서 이해한다.


 

Generic이란?


제네릭은 클래스 내부에서 사용할 데이터 타입을 외부에서 파라미터 형태로 지정하면서 데이터 타입을 일반화 한다.

제네릭은 가상의 자료형을 정의함으로써 객체를 정의할 때 타입 매개변수를 선언하여 사용할 수 있다.

 

 

Generic의 일반적인 표현법


타입인자 설명
<T> Type
<E> Element
<K> Key
<N> Number
<V> Value
<R> Result

 

 

Generic의 필요성


제네릭이 등장하기 이전에는 여러 타입을 사용하기 위해서
모든 클래스의 최상위 Object 클래스를 이용해 설계하였다.

Object 클래스자체를 이용하는 것이 나쁜것은 아니지만, 기능(함수)를 사용하기 위해서는
수동 타입 변환이 많이 발생하게 되어 코드가 복잡해지고, 개발자의 실수로 잘못된 타입 변환을 할 가능성이 있다. 이를 방지하기 위하여 생긴것이 제네릭이다. (JDK 1.5버전 이상부터 지원)

 

 

Generic의 장점


  • 타입체크 / 형변환을 생략하여 간결한 코드 작성이 가능하다.
  • 클래스나 메소드 내부에서 사용되는 객체의 타입 안정성을 제공한다.

 

 

1. 본격 Generic학습 [Generic class, Generic method]


[1] Generic class


1. Generic class의 정의


// 접근 제어자 class 클래스명 <T> {//구현부}
// 접근 제어자 class 클래스명 <K, V> {//구현부}

public class GenericTest<T> {...}
public interface GenericInterface<T> {...}
public class MultiGenericTest<K, V> {...}

 

 

2. Generic class의 지정된 가상타입을 이용하는 방법


  • 제네릭 타입(가상타입)을 이용해 Generic class 설계 하기
public class GenericTest<T> {
    private T t;
    public T get() {return t;}
    public void set(T t) {t.this = t;}
}

가상타입(제네릭 타입, 타입매개변수, 타입변수) : <T>와 같은 것을 의미한다.

 

가상타입 <T>를 사용하기 위해서는 필드의 타입이나, 메소드의 반환값, 메소드의 매개변수 등에 가상타입 T를 적어줌으로써 타입을 지정해준다.

 

 

[반드시 인지해야하는 제네릭의 특징]

  1. 제네릭 타입 (가상타입)은 (객체 생성시점의) 컴파일시에 컴파일러에 의해 자동으로 검사되어 타입 변환된다.
  2. 타입 변환되어지고, 컴파일된 class 파일에는 어떠한 제네릭 타입도 포함되지 않게 된다.

 

 

  • 설계된 Generic class를 이용하는 예제
public static void main(String[] args){
    GenericTest<String> genericTest = new GenericTest<String>();
    genericTest.set("제네릭 박살!");
    String str = genericTest.get();
    System.out.println(str); // System.out.println(genericTest.get());
}
  • 출력값

image

 

 

3. Generic 와일드 카드


<?> // 타입 매개변수에 모든 타입을 사용한다.
<? extends T> // T타입과 T타입을 상속받는 하위 클래스 타입만 사용한다.
<? super T> // T타입과 T타입을 상속받는 상위 클래스 타입만 사용한다.

 

 

[2] Generic method


클래스 전체를 제네릭으로 사용할 수 있지만, 클래스 내부의 특정 메소드만 제네릭으로 선언하여 사용하는 방법

  • 제네릭 메소드를 정의하는 시점에서는 실제 어떤 타입이 입력 되는지 알 수 없다.
  • 따라서 제네릭 메소드 안에서는 가상타입.length() (t.length())와 같이 사용이 불가능 하다는 것이다.
  • 왜냐면... 가상타입에 뭐가 들어올지 모르니까!!!!!!!!!
  • 하지만 Object 클래스 같은 경우는 모든 클래스의 조상이므로 Object 클래스의 메소드는 사용이 가능하다.
  • java.lang.Object 클래스의 메소드

 

잠깐!!!! Generic classGeneric method의 타입지정 시점의 차이

  • Generic class : 객체 생성 시점에 실제 타입의 지정이 이루어진다.
  • Generic method : 호출되는 시점에 실제 타입의 지정이 이루어진다.

 

  • 제네릭 타입(가상타입)을 이용해 Generic method 설계하기
class GenericMethodOnly {
    public <T> T get(T t) { return t; }
    public <K, V> void getPrint(K k, V v) {
        System.out.println(k + "아마도 " + v + "번 쯤 봤을려나...");
    }
}

 

  • Generic method 이용하기
public static void main(String[] args){
    GenericMethodOnly genericMethodOnly = new GenericMethodOnly();

    System.out.println(genericMethodOnly.get("제네릭 박살"));
    // System.out.println(genericMethodOnly.<String>get("제네릭 박살"));

    genericMethodOnly.getPrint("제네릭만 몇 번째인지 ㅡㅡ ", 30);
    // genericMethodOnly.getPrint("제네릭만 몇 번째인지 ㅡㅡ ", 30);
}

 

  • 결과값

image