자바 오버로딩 문제 Overloading a method: both methods have same erasure

Yunny.Log ·2023년 1월 13일
2

Debugging

목록 보기
60/69
post-thumbnail

문제상황

  • 위와 같이 생성자를 만드는 중에, 둘의 매개변수에 있어서 차이가 있으니 (List A, List b 로) 오버로딩이 자연스레 될 것이라 예상했었습니다.

  • 그러나 위의 생성자에 빨간 줄이 떴습니다.

  • 에러 메시지는 아래와 같습니다.

    'SchematicDesign(Pcb, List, Member)' clashes with 'SchematicDesign(Pcb, List, Member)'; both methods have same erasure

  • 이 상황을 이해하기 위해 자바의 Generic Type erasure 에 대해서 알아볼 필요가 있을 것 같습니다.

  • Type erasure 란 원소 타입을 컴파일 타입에만 검사하고 런타임에는 해당 타입 정보를 알 수 없는 것입니다.
  • 한마디로, 컴파일 타임에만 타입 제약 조건을 정의하고, 런타임에는 타입을 제거합니다.
  • 이를 더 자세히 알아봅시다. 자바에는 구체화와 비 구체화 타입이 존재한다구 합니다.

배열은 구체화(reify)되고, 제네릭은 비 구체화(non-reify)가 됩니다.

  • 구체화 타입(reifiable type): 자신의 타입 정보를 런타임에도 알고 있는 것
    비 구체화 타입(non-reifiable type): 런타임에는 소거(erasure)가 되기 때문에 컴파일 타임보다 정보를 적게 가지는 것
  • 여기서 바로 소거(erasure)가 나옵니다. 바로 제네릭은 컴파일 타임에 타입 체크를 한 후에 런타임에는 타입을 지우는 방법을 사용하고 있습니다.
  • 아하 이해가 되었습니다. 제네릭의 경우는 런타임 시점에 타입을 지워버립니다.
  • 저는 이 사실을 모르고 생성자는 List 부분에서 List <A>, List <B>로 매개변수에 차이가 있어서 정상적으로 오버로딩이 될 줄 알았습니다.
  • 그러나 사실은 런타임 시점에 두 List 모두 그저 타입이 떨어져나간 List로 만들어집니다. 그래서 오버로딩이 정상 수행되기 어려워지겠죠, 매개변수가 같아졌으니 말입니다.
  • 저와 똑같은 상황의 스택오버플로우를 발견했습니다.

  • 답변이 저의 추측과 같았습니다. 결국 둘다 똑같은 List가 되어버리는 것이지요.

  • 이런 런타임 시점의 제네릭의 특성에 대해서 깨달을 수 있는 소중한 경험이었네요.

reference

erasure, 공변, 불공변, 구체화, 비구체화 개념 : https://devlog-wjdrbs96.tistory.com/263

https://stackoverflow.com/questions/28830522/java-error-both-methods-have-same-erasure-for-generics

plus 공변 , 불공변 (from https://devlog-wjdrbs96.tistory.com/263)

  • 공변 : 자기 자신과 자식 객체로 타입 변환을 허용
    • 자기랑 똑같지 않아도 자기 자식이면 들어오게 허용해주는 것입니다.
Object[] before = new Long[1];
  • 불공변 : List<String>List<Object>가 있을 때 두 개의 타입은 전혀 관련 X
    • 나랑 동일한 타입만이 같은 것이라고 인식합니다.

0개의 댓글