Java

제네릭 - 제한된 타입 파라미터/ 와일드카드

공부처음하는사람 2024. 7. 11. 15:45

 

경우에 따라 타입 파라미터를 대체하는 구체적인 타입을 제한할 필요가 있다. 

숫자를 연산하는 제네릭 메소드는 대체 타입으로 Number 또는 자식클래스 (Byte, Short, Integer ....)로 제한 할 필요가 있다.

 

상위 타입은 클래스뿐만 아니라 인터페이스도 가능하다. 인터페이스라고 해서 implements를 사용하진 않는다.

 

package ch13.sec04;

public class GenericEx {
    // 제한된 타입 파라미터를 갖는 제네릭 메소드
    public static <T extends Number> boolean compare(T t1, T t2) {
        System.out.println("compare: " + t1.getClass().getSimpleName() + ", " +
                t2.getClass().getSimpleName() + ")");

        double v1 = t1.doubleValue();
        double v2 = t2.doubleValue();

        return (v1 == v2);
    }

    public static void main(String[] args) {

        boolean result1 = compare(10, 20);
        System.out.println(result1);
        System.out.println();

        boolean result2 = compare(4.5, 4.5);
        System.out.println(result2);
    }
}

 

 타입 클래스가 Number타입으로 제한되었다. (<T extends Number> 구문) 

이렇게 되면 Object의 메소드 뿐만 아니라 Number가 가지고 있는 메소드도 사용할 수 있다.

 

doubleValue() 메소드는 Number 타입에 정의되어있는 메소드이다. (API 도큐멘트 참고)

 

와일드카드 타입 파라미터

제네릭 타입을 매개값이나 리턴 타입으로 사용할 때 타입 파라미터로 ?(와일드카드)를 사용할 수 있다.

 

 

리턴타입 메소드명(제네릭타입<? extends Student> 변수 { ... }
리턴타입 메소드명(제네릭타입<? super Worker> 변수 { ... }

 

? super 와 ? extends의 차이를 잘 기억하자

 

package ch13.sec05;

public class Course {

    // 모든사람 등록
    public static void registerCourse1(Applicant<?> applicant) {
        System.out.println(applicant.kind.getClass().getSimpleName() +
                "이(가) Course1을 등록함");
    }

    // 학생만
    public static void registerCourse2(Applicant<? extends Student> applicant) {
        System.out.println(applicant.kind.getClass().getSimpleName() +
                "이(가) Course2를 등록함");
    }

    public static void registerCourse3(Applicant<? super Worker> applicant) {
        System.out.println(applicant.kind.getClass().getSimpleName() +
                "이(가) Course3를 등록함");
    }
}

 

package ch13.sec05;

public class GenericEx {
    public static void main(String[] args) {

        // 모든사람 신청
        Course.registerCourse1(new Applicant<Person>(new Person()));
        Course.registerCourse1(new Applicant<Worker>(new Worker()));
        Course.registerCourse1(new Applicant<Student>(new Student()));
        Course.registerCourse1(new Applicant<HighStudent>(new HighStudent()));
        Course.registerCourse1(new Applicant<MiddleStudent>(new MiddleStudent()));
        System.out.println();

        // 학생만

        Course.registerCourse2(new Applicant<Student>(new Student()));
        Course.registerCourse2(new Applicant<HighStudent>(new HighStudent()));
        Course.registerCourse2(new Applicant<MiddleStudent>(new MiddleStudent()));

        // 직장인만

        Course.registerCourse3(new Applicant<Person>(new Person()));
        Course.registerCourse3(new Applicant<Worker>(new Worker()));
    }
}

 

 

 

이 내용을 알아둬야 하는 이유는 나중에 API 도큐멘트를 읽고 이해를 하기 위함이다. 잘 알아두자

'Java' 카테고리의 다른 글

제네릭(Generic) 메소드  (0) 2024.07.11
제네릭 (Generic)  (0) 2024.07.10
어노테이션  (0) 2024.07.10
정규표현식  (0) 2024.07.10
래퍼 (wrapper) 클래스  (0) 2024.07.10