위의 클래스는 컬렉션을 종류별로(집합,리스트,아니면 다른 종류의 컬렉션) 분류하는 것이다. 이 프로그램은 Set,List,Unkown Collection을 순서대로 출력하지 않을까 생각하겠지만 실제로는 "Unknown Collection"을 세 번 출력할 뿐이다. classify 메서드가 오버로딩되어 있으며, 오버로딩된 메서드 가운데 어떤 것이 호출될지는 컴파일 시점에 결정되기 때문이다. 위의 반복문 컴파일 시점 자료형은 전부 Collection<?> 으로 동일하다. 따라서 전부 "Unknown Collection"이 출력되는 것이다.
오버로딩된 메서드는 정적(컴파일 시점)으로 선택되지만, 재정의된 메서드는 동적(실행 시점)으로 선택되기 때문이다. 즉 재정의 메서드 가운데 하나를 선택할 때는 객체의 컴파일 시점 자료형은 아무런 영향을 주지 못하며, 오버로딩에서는 반대로 실행시점 자료형이 아무 영향도 주지 못한다.. 실행될 메서드는 컴파일 시에, 인자의 컴파일 시점 자료형만을 근거로 결정된다.
이러한 오버로딩의 문제점을 해결하기 위해서는 아래와 같이 작성하는 것이 최선이다. 오버로딩 된 세 classify 메서드를 하나로 합치고, 그 안에서 instanceof 연산자를 사용해 자료형을 검사하는 것이다.
오버로딩을 사용할 떄는 혼랍스럽지 않게 사용할 수 있도록 주의해야 한다. 처음 예제처럼 결과값이 예측하기 힘든 상황처럼 말이다. 혼란을 피하는 안전하고 보수적인 전략은, 같은 수의 인자를 갖는 두 개의 오버로딩 메서드를 API에 포함시키지 않는 것이다.
이러한 중복을 피하기 위해서는 작명 패턴(writeBoolean(boolean) , writeInt(int) ...)과 같은 방법을 사용할 수 있는데, 오버로딩에 비해 각 메서드에 정의되는 read메서드를 정의할 수 있다.
같은 수의 인자를 받는 오버로딩 메서드가 많더라도, 어떤 오버로딩 메서드가 주어진 인자 집합을 처리할 것인지가 분명히 결정된다면 혼란스럽지 않을 것이다. 이렇게 확실히 결정된다는 것은 두 자료형을 서로 형변환 할 수 없다는 것이다. 이 조건이 충족되면 주어진 인자 집합에 오버로딩을 적용 했을 때 인자의 실행시점 자료형에 따라 오버로딩 메서드가 결정될 수 있다.
요약
메서드를 오버로딩 할 수 있다고 해서 반드시 그래야 하는 것은 아니다. 인자 개수가 같은 오버로딩 메서드를 추가하는 것은 일반적으로 피해야 한다. 형변환만 추가하면 같은 인자 집합으로 여러 오버로딩 메서드를 호출할 수 있는 상황은 피하는 것이 좋다.