자바에서 제네릭 메서드는 메서드의 동작을 호출 시점에 지정된 타입으로 일반화할 수 있게 해줍니다. 제네릭 메서드를 사용하면 특정 타입에 종속되지 않고 다양한 타입을 처리할 수 있어 코드의 재사용성을 높이고, 타입 안전성을 확보할 수 있습니다.
1. 제네릭 메서드의 필요성
제네릭 메서드는 타입 매개변수를 받아들여, 메서드 호출 시점에 타입을 결정하게 합니다. 이를 통해 코드 중복을 줄이고, 타입에 독립적인 메서드를 작성할 수 있습니다.
1.1. 제네릭 메서드를 사용하지 않는 예시
제네릭을 사용하지 않은 메서드는 여러 타입을 처리하기 위해 오버로딩을 사용하거나, Object 타입을 사용하여 타입을 통일하는 경우가 많습니다.
//제네릭 메서드를 사용하지 않은 경우의 예시
public class Utils {
// 서로 다른 타입의 두 값을 비교해 더 큰 값을 반환하는 메서드
public static int max(int a, int b) {
return (a > b) ? a : b;
}
public static double max(double a, double b) {
return (a > b) ? a : b;
}
}
위 코드에서는 max 메서드가 두 개의 다른 타입(int, double)을 처리하기 위해 각각 메서드를 오버로딩하고 있습니다. 이는 코드의 중복을 증가시키고, 새로운 타입을 추가할 때마다 새로운 메서드를 작성해야 합니다.
1.2. 제네릭 메서드를 사용한 예시
제네릭 메서드를 사용하면 타입에 의존하지 않고, 더 간결하고 재사용 가능한 코드를 작성할 수 있습니다.
//제네릭 메서드를 사용한 max 메서드의 개선된 예시
public class Utils {
// 제네릭 메서드를 사용하여 타입에 독립적인 max 메서드 작성
public static <T extends Comparable<T>> T max(T a, T b) {
return (a.compareTo(b) > 0) ? a : b;
}
}
<T extends Comparable<T>>: 제네릭 타입 매개변수 T는 Comparable 인터페이스를 구현해야 함을 명시하여, compareTo 메서드를 사용할 수 있도록 보장합니다.
Comparable 인터페이스 구현 예시
제네릭 타입 매개변수 T가 Comparable<T> 인터페이스를 구현하여, compareTo 메서드를 사용할 수 있도록 보장하는 코드
// Person 클래스가 Comparable 인터페이스를 구현
class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Comparable 인터페이스의 compareTo 메서드를 구현
@Override
public int compareTo(Person other) {
// 나이를 기준으로 비교 (나이가 적은 순서로 정렬)
return Integer.compare(this.age, other.age);
}
@Override
public String toString() {
return name + " (" + age + ")";
}
}
// 제네릭 메서드: T가 Comparable<T>를 구현해야만 사용할 수 있음
public class Main {
// 두 값을 비교하여 큰 값을 반환하는 제네릭 메서드
public static <T extends Comparable<T>> T max(T a, T b) {
return (a.compareTo(b) > 0) ? a : b;
}
public static void main(String[] args) {
// Integer, String, Person 모두 Comparable을 구현하므로 max 메서드에서 사용 가능
System.out.println(max(10, 20)); // Integer 비교, 출력: 20
System.out.println(max("apple", "banana")); // String 비교, 출력: banana
// Person 클래스의 비교
Person person1 = new Person("Alice", 30);
Person person2 = new Person("Bob", 25);
// Person의 나이를 비교하여 더 나이가 많은 사람을 반환
System.out.println(max(person1, person2)); // 출력: Alice (30)
}
}
코드 설명
Person 클래스:
Person 클래스는 Comparable<Person> 인터페이스를 구현하고, compareTo 메서드를 오버라이드합니다.
compareTo 메서드는 Person 객체를 나이를 기준으로 비교하여, 정렬이나 크기 비교 시 사용됩니다.
max 제네릭 메서드:
<T extends Comparable<T>>: T는 Comparable<T>를 구현해야만 사용할 수 있습니다. 이는 compareTo 메서드를 호출할 수 있도록 보장합니다.
max(T a, T b): 두 T 타입의 객체를 비교하여 더 큰 값을 반환합니다.
main 메서드에서의 사용 예시:
Integer, String, Person 등 Comparable을 구현한 다양한 타입에서 max 메서드를 사용할 수 있습니다.
Person 객체를 비교할 때는 나이를 기준으로 비교하여 더 큰(나이가 많은) 객체를 반환합니다.
이렇게 작성된 제네릭 메서드는 int, double, String 등 서로 다른 타입에 대해 작동할 수 있습니다.