Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

개발자 도전기

[JAVA] 제네릭(Generic) 본문

개발공부/JAVA

[JAVA] 제네릭(Generic)

jnnjnn 2024. 3. 19. 21:39

제네릭이란?

제네릭이란 결정되지 않은 타입을 파라미터로 처리하고 실제 사용할 때 파라미터를 구체적인 타입으로 대체시키는 기능이다.

 

다음과 같이 사용할 수 있다.

public class 클래스명 <T>{
	public T content;
}

 

<T>는 T가 타입 파라미터임을 뜻하는 기호로, 타입이 필요한 자리에 T를 사용할 수 있음을 알려주는 역할을 한다.

해당 클래스의 T는 아직 정해지지 않았지만, 객체가 생성될 시점에 다른 타입으로 대체된다.

 

제네릭 타입

제네릭 타입은 결정되지 않은 타입을 파라미터로 가지는 클래스와 인터페이스를 말한다. 제네릭 타입은 선언부에 '<>' 부호가 붙고, 그 사이에 타입 파라미터들이 위치한다.

public class 클래스명 <A, B>{}
public interface 인터페이스명<A, B, ...>{}

 

타입 파라미터는 일반적으로 대문자 알파벳 한 글자로 표현한다.

외부에서 제네릭 타입을 사용하려면 타입 파라미터에 구체적인 타입을 지정해야 하고, 지정하지 않으면 Object 타입이 암묵적으로 사용된다.

public class C02GenericType {
    public static void main(String[] args) {
        C02Box<String> box1 = new C02Box<String>(); // 타입 파라미터에 String 대입
        C02Box<Integer> box2 = new C02Box<Integer>(); // 타입 파라미터에 Integer 대입

        box1.setItem("java");
        String item = box1.getItem();

        box2.setItem(300);
        Integer item1 = box2.getItem();
    }
}

class C02Box<T> {
    private T item;

    public T getItem() {
        return item;
    }

    public void setItem(T item) {
        this.item = item;
    }
}

 

타입 파라미터는 기본적으로 Object 타입으로 간주되므로 Object가 가지고 있는 메소드 (hashCode(), equals(), toString())를 호출할 수 있다.

 

 

제네릭 메소드

제네릭 메소드는 타입 파라미터를 가지고 있는 메소드를 말한다. 제네릭 메소드는 리턴 타입 앞에 <> 기호를 추가하고 타입 파라미터를 정의한 뒤, 리턴 타입과 매개변수 타입에서 사용한다.

 

public <A, B, ... > 리턴타입 메소드명(매개변수, ..){}

 

다음 boxing() 메소드는 타입 파라미터를 <T>로 정의하고 매개변수 타입과 리턴 타입에서 T를 사용한다. 리턴 타입은 T를 내용물로 갖는 Box 객체이다.

 

public class Box<T> {
    private T t;

    public T getT() {
        return t;
    }

    public void set(T t) {
        this.t = t;
    }
}

public class GenericExample {
    public static <T> Box<T> boxing(T t) {
        Box<T> box = new Box<>();
        box.set(t);
        return box;
    }

    public static void main(String[] args) {
        Box<Integer> box1 = boxing(100);
        int intValue = box1.getT();
        System.out.println(intValue);

        Box<String> box2 = boxing("홍길동");
        String strValue = box2.getT();
        System.out.println(strValue);
    }
}

 

 

제한된 타입 파라미터

경우에 따라서는 타입 파라미터를 대체하는 구체적인 타입을 제한할 필요가 있다. 예를 들어 숫자를 연산하는 제네릭 메소드는 대체 타입으로 Number 또는 그 자식 클래스로 제한할 필요가 있다.

 

이처럼 모든 타입으로 대체할 수 없고, 특정 타입과 자식 또는 구현 관계에 있는 타입만 대체할 수 있는 타입 파라미터를 제한된 타입 파라미터라고 한다.

 

public <T extends 상위타입> 리턴타입 메소드(매개변수, ...) {}

public <T extends Number> boolean compare(T t1, T t2){
	double v1 = t1.doubleValue();
    double v2 = t2.doubleValue(); // Number의 doubleValue() 메소드 사용
    return (v1 == v2);
}

 

위와 같이 타입 파라미터가 Number 타입으로 제한되면서 Number의 메소드를 사용할 수 있다.

 

와일드카드 타입 파라미터

제네릭 타입을 매개값이나 리턴 타입으로 사용할 때 타입 파라미터로 ?(와일드카드)를 사용할 수 있다. ?는 범위에 있는 모든 타입으로 대체할 수 있다는 표시이다.

다음과 같이 상속 관계를 표시하여 사용한다.

제네릭타입<? extends Number>

제네릭타입<? super Object>

 

 

와일드 카드의 사용 예시이다

public class C06WildCard {
    public static void main(String[] args) {
        Integer v1 = 100;
        Number v2 = v1;
        Double v3 = 3.14;
        Number v4 = v3;
        Object v5 = v2;
        Object v6 = v4;

        C06Box<Integer> b1 = new C06Box<>();
//        C06Box<Number> b2 = b1; 안됨
        C06Box<? extends Number> b2 = b1;
        C06Box<Double> b3 = new C06Box<>();
        C06Box<? extends Number> b4 = b3;
        C06Box<Object> b5 = new C06Box<>();
//        C06Box<? extends  Number> b6 = b5; 안됨
        C06Box<? super Number> b7 = b5;


    }
}

class C06Box<T> {
    private T item;

    public T getItem() {
        return item;
    }

    public void setItem(T item) {
        this.item = item;
    }
}

'개발공부 > JAVA' 카테고리의 다른 글

[JAVA] Stack, Queue  (0) 2024.03.20
[JAVA] Map 컬렉션  (0) 2024.03.20
[JAVA] 포장 클래스  (0) 2024.03.19
[JAVA] Object 클래스  (0) 2024.03.19
[JAVA] TreeSet  (0) 2024.03.19