작성
·
50
0
안녕하세요! 이번에 정처기 문제에서 타입 이레이저 관련 문제가 나왔는데, 궁금한 점이 생겨서 질문 올려봅니다.
class Printer {
void print(Integer a) {
System.out.print("A" + a);
}
void print(Object a) {
System.out.print("B" + a);
}
void print(Number a) {
System.out.print("C" + a);
}
}
public class Gisafirst {
public static void main(String[] args) {
new Container<>(0).print();
}
public static class Container<T> {
T value;
public Container(T t) {
value = t;
}
public void print() {
new Printer().print(value);
}
}
}
제가 이해한 바로는, 강의에서 설명해주신대로 new Container<>(0)
에서
public static class Container<Integer> {
Integer value;
public Container(Integer t) {
value = t;
}
public void print() {
new Printer().print(value);
}
}
컴파일러가 컴파일 시점에 이렇게 이해하고 나서 컴파일 종료 후, 타입 소거가 일어나서, Object로 변환한다고 이해했습니다.
그래서 print 메서드를 호출할 때 value는 Object 타입이므로 B0가 출력되는 것이죠.
여기서 궁금한 점은 바로 print의 오버로딩 메서드 선택 시점입니다. 제가 찾아본 바로는 오버로딩 메서드 선택시점은 컴파일 단계에서 이루어진다로 알고있습니다.
그렇다면 동작방식이 컴파일 종료 후 타입 소거가 일어나는게 아니라, 정확히는
"컴파일 시작 - 타입 소거 - 오버로딩 메서드 선택 - 컴파일 종료 - 런타임" 이런식으로 일어나는건가용?
아니면 어디서 오해하고 있는지 궁금합니다!
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. 구준형님.
타입 이레이저(Type Erasure)는 컴파일 시점에 발생하며, 제네릭 타입 정보는 런타임 전에 소거됩니다. 질문하신 상황에서는 타입 이레이저와 메서드 오버로딩 간의 관계를 이해하는 것이 중요합니다.
컴파일 시 타입 소거가 이루어짐: 제네릭 클래스나 메서드의 타입 파라미터는 컴파일 과정에서 소거되어, 더 구체적인 타입 캐스트로 대체됩니다. 예를 들어, new Container<>(0)
에서 Container<Integer>
는 컴파일 시 Container<Object>
로 변경되고, 내부에서 value
타입도 Object
로 됩니다.
메서드 호출 결정: 자바에서 오버로딩 메서드 호출은 컴파일 타임에 진행됩니다. 즉, 구체적으로 어느 메서드를 호출할지를 타입 정보를 기반으로 결정합니다. 구체적 타입(Integer)이 호출할 메서드를 선택하는 데 기초합니다. 그러나 이 경우, 타입 이레이저로 인해 Object
가 됩니다.
결국, 오버로딩된 메서드를 선택할 때는 value
가 컴파일 단계에서 이미 객체로 인식되므로 print(Object a)
메서드가 선택됩니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.