개발일지/Java

Java 제네릭 (Generic)

E-room 2022. 9. 14. 18:33
728x90
타입을 구체적으로 지정하는 것이 아니라, 추후에 지정할 수 있도록 일반화해두는 것

 

작성한 클래스 또는 메서드의 코드가 특정 데이터 타입에 얽매이지 않게 해 둘 때 사용한다.

 

 

제네릭 클래스

하나의 클래스로 모든 타입의 데이터를 저장할 수 있는 인스턴스를 만들 수 있다

 

제네릭 클래스 생성

* static은 사용불가하니 참고

class Basket { // 제네릭 미사용시 타입별로 모두 만들어야 한다 (String, Integer, ...)
    private String item;
    Basket(String item) {
        this.item = item;
    }
    public String getItem() {
        return item;
    }
    public void setItem(String item) {
        this.item = item;
    }
}

class Basket<T> { // 제네릭을 사용하면 하나의 클래스로 모든 타입의 데이터를 대응할 수 있다
    private T item;
    public Basket(T item) {
        this.item = item;
    }
    public T getItem() {
        return item;
    }
    public void setItem(T item) {
        this.item = item;
    }
}

 

인스턴스화

// Basket 클래스 내의 T를 String으로 바꾸어라
Basket<String> basket1 = new Basket<String>("기타줄"); // new Basket<String>의
                                                     // String은 생략가능
// Integer로 바꾸어라
Basket<Integer> basket2 = new Basket<Integer>(1);

 

제한된 제네릭 클래스

인스턴스화할 때 타입을 제한할 때 사용한다

// Basket 클래스를 인스턴스화할 때 타입으로 Flower 클래스의 하위 클래스만 지정하도록 제한
class Flower { ... }
class Rose extends Flower { ... }
class RosePasta { ... }

class Basket<T extends Flower> {
    private T item;
		...
}

public static void main(String[] args) {

		// 인스턴스화 
		Basket<Rose> roseBasket = new Basket<>();
		Basket<RosePasta> rosePastaBasket = new Basket<>(); // 에러
}

제네릭 메서드

클래스 전체를 제네릭으로 선언할 수도 있지만, 클래스 내부의 특정 메서드만 제네릭으로 선언할 수 있다.

 

클래스와 달리 static 사용 가능

제네릭 메서드의 타입 매개변수 선언은 반환 타입 앞에서 이루어지며, 해당 메서드 내에서만 선언한 타입 매개변수를 사용할 수 있다.

class Basket {
    ...
    public <T> void add(T element) {
        ...
    }
}

 

제네릭 메서드의 타입 매개변수는 제네릭 클래스의 타입 매개변수와 별개의 것이다

제네릭 메서드의 타입 지정은 메서드가 호출될 때 이루어진다

class Basket<T> {                    // 1 : 여기에서 선언한 타입 매개변수 T와 
    ...
    public <T> void add(T element) { // 2 : 여기에서 선언한 타입 매개변수 T는 서로 다른 것입니다.
        ...
    }
}
Basket<String> basket = new Bakset<>(); // 위 예제의 1의 T가 String으로 지정됩니다. 
basket.<Integer>add(10);                // 위 예제의 2의 T가 Integer로 지정됩니다. 
basket.add(10);                         // 타입 지정을 생략할 수도 있습니다.

와일드카드

어떠한 타입으로든 대체될 수 있는 타입 파라미터를 의미, 기호(?)로 사용 가능

일반적으로 와일드카드는 extends와 super 키워드를 조합하여 사용한다

 

  • <? extends T>
    • 와일드카드에 상한 제한을 둔다
    • T와 T를 상속받는 하위 클래스 타입만 타입 파라미터로 받을 수 있다
  • <? super T>
    • 와일드카드에 하한 제한을 둔다
    • T와 T의 상위 클래스만 타입 파라미터로 받을 수 있다
  • <?>
    • <? extends Object>와 같다
    • 즉, 모든 클래스 타입을 타입 파라미터로 받을 수 있다

 

728x90