Language/JAVA

[JAVA] 타입 파라미터

IT수정 2024. 10. 16. 16:53

제한된 타입 파라미터

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

 

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

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

 

상위 타입은 클래스뿐만 아니라 인터페이스도 가능하다. 인터페이스라고 해서 implements를 사용하지는 않는다. 다음은 Number 타입과 자식 클래스에만 대체 가능한 타입 파라미터를 정의한 것이다.

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

 

타입 파라미터가 Number 타입으로 제한되면서 Object의 메서드뿐만 아니라 Number가 가지고 있는 메서드도 사용할 수 있다. 위 코드에서 doubleValue() 메서드는 Number 타입에 정의되어 있는 메서드로, double 타입 값을 리턴한다.

 

예제 코드

package ch13.sec03;

public class GenericExample {
	
	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) {
		// TODO Auto-generated method stub
		boolean result1 = compare(10, 20);
		System.out.println(result1);
		System.out.println();
		
		boolean result2 = compare(4.5, 4.5);
		System.out.println(result2);
	}

}

 

출력 결과

compare(Integer, Integer)
false

compare(Double, Double)
true

 

와일드카드 타입 파라미터

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

 

예제 코드

package ch13.sec04;

public class Person {
}

class Worker extends Person {
}

class Student extends Person {
}

class HighStudent extends Student {
}

class MiddleStudent extends Student {
}
package ch13.sec04;

public class Applicant<T> {
	public T kind;
	
	public Applicant(T kind) {
		this.kind = kind;
	}
}
package ch13.sec04;

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.sec04;

public class GenericExample {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		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()));
		System.out.println();
		
		Course.registerCourse3(new Applicant<Person>(new Person()));
		Course.registerCourse3(new Applicant<Worker>(new Worker()));
	}

}

 

출력 결과

Person이(가) Course1을 등록함
Worker이(가) Course1을 등록함
Student이(가) Course1을 등록함
HighStudent이(가) Course1을 등록함
MiddleStudent이(가) Course1을 등록함

Student이(가) Course2을 등록함
HighStudent이(가) Course2을 등록함
MiddleStudent이(가) Course2을 등록함

Person이(가) Course3을 등록함
Worker이(가) Course3을 등록함

'Language > JAVA' 카테고리의 다른 글

[JAVA] 스레드 메서드  (0) 2024.10.17
[JAVA] 멀티 스레드  (2) 2024.10.17
[JAVA] 제네릭 메서드  (0) 2024.10.16
[JAVA] 제네릭 타입  (0) 2024.10.16
[JAVA] 제네릭  (0) 2024.10.16