public class CollectionClassifier {
public static String classify(Set<?> s) {
return "집합";
}
public static String classify(List<?> list) {
return "리스트";
}
public static String classify(Collection<?> c) {
return "그 외";
}
public static void main(String[] args) {
Collection<?>[] collections = {
new HashSet<>(),
new ArrayList<>(),
new HashMap<String, String>().values()
};
for (Collection<?> c : collections) {
System.out.println(classify(c));
}
}
}
코드를 실행하면 어떤 결과가 나올까요? 집합, 리스트, 그 외를 차례로 출력할 것 같지만
실제로는 그 외만 세 번 출력됩니다. 그 이유는 다중정의(overloading)된 classify 중 어느 메서드를 호출할지가
컴파일타임에 정해지기 때문입니다.
intellij에서 Set, List를 매개 변수로 받는 classify 메서드는 사용되지 않는다고 나온다.
이처럼 직관과 어긋나는 이유는 재정의한 메서드(Overiding)는 동적(런타임)에 선택되고, 다중정의 한 메서드(overoding)는 정적(컴파일타임)으로 선택되기 때문입니다.
다중정의가 혼동을 일으키는 상황을 피하는 방법
- 매개변수 수가 같은 다중정의는 만들지 않는다.
- 서로 다른 함수형 인터페이스도 같은 위치의 인수로 받지 말자.
- 다중정의하는 대신 메서드 이름을 다르게 짓는다.
- ObjectOutputStream클래스에 writeInt(int), writeLong(long)
- 위에 방법들이 불가능하다면 다중정의 메서드들이 모두 동일하게 동작하도록 만들자
public boolean contentEquals(StringBuffer sb) // java 4
public boolean contentEquals(CharSequence cs) // java 5
상대적으로 특수한(StringBuffer) 다중정의 메서드가 덜 특수한(CharSequence) 다중 정의 메서드로 일을 넘겨버리면
동일한 동작을 보장할 수 있다.
'effective java' 카테고리의 다른 글
Item 53. 가변인수는 신중히 사용하라 (0) | 2022.03.06 |
---|---|
Item46. 스트림에서는 부작용 없는 함수를 사용하라 (0) | 2022.03.06 |
Item 35. ordinal 메서드 대신 인스턴스 필드를 사용하라 (0) | 2022.03.06 |
Item32. 제네릭과 가변인수를 함께 쓸 때는 신중하라 (0) | 2022.01.23 |
댓글