유형 삭제는 사용자가 켜거나 끌 수있는 단순한 바이트 코드 이상의 기능입니다.
전체 런타임 환경의 작동 방식에 영향을줍니다. 제네릭 클래스의 모든 인스턴스의 제네릭 형식을 쿼리 할 수있게하려면 런타임에 해당하는 메타 정보가 제네릭 클래스의 각 개체 인스턴스화에 대해 만들어 지도록 함을 의미합니다.당신은 세 개의 객체를 생성하지 않는 new ArrayList<String>(); new ArrayList<Number>(); new ArrayList<Object>()
을 작성하는 경우가 이전에 존재하지 않은 경우
, 당신은 잠재적으로, 세 개의 추가 메타 유형, ArrayList<String>
, ArrayList<Number>
을 반영하는 개체 및 ArrayList<Object>
을 만들 수 있습니다.
대표적인 응용 프로그램에서 사용되는 다양한 List
서명이 있다고 가정합니다. 대부분이 그러한 Reflection의 가용성이 필요한 곳에서는 사용되지 않았습니다 (이 기능이 없기 때문에 현재 , 그들 모두는 그런 반사없이 일합니다.)
물론 1,000 개의 다른 일반 목록 유형에는 천개의 다른 일반 반복기 유형, 천개의 스플 리터레이터 및 스트림 구현을 암시하며 구현의 내부 클래스도 계산하지 않습니다.
그리고 심지어 이것은 객체 할당이없는 장소에서 영향을받습니다. Collections.emptyList()
, Function.identity()
또는 Comparator.naturalOrder()
등은 호출 할 때마다 동일한 인스턴스를 반환합니다. Particalarar가 캡쳐 된 일반 유형을 반영 할 수 있도록 조사 할 수 있다고 주장하면 더 이상 작동하지 않습니다. 당신이
List<String> list=Collections.emptyList();
List<Number> list=Collections.emptyList();
를 작성하는 경우 그래서 당신은 그들 각각의 getClass()
또는 미래 동등한의 다른보고, 두 가지 인스턴스를받을 수있을 것입니다.
은이 능력을하고자하는 사람들이 반사적으로 하나 개의 특정 매개 변수는 실제로 두 개 또는 세 가지 유형 중 하나인지를 알 수 있다면 좋을 것 그들의 특정한 방법에 좁은 관점을 가지고 보이지만, 수천 개의 제네릭 클래스에 대한 잠재적 인 수백 또는 수천 개의 일반적인 인스턴스화에 대한 메타 정보를 운반하는 데 대한 무게를 생각하지 마십시오.
여기는 우리가 얻은 것, 즉 반사 형을 통해 발견 된 정보로 인해 코드의 동작을 변경하는 의심스러운 코딩 스타일을 지원하는 능력에 대해 묻는 것입니다.
대답 지금까지 오직 소거 형을 제거 쉽게 양태를 어드레싱 욕구는 실제 인스턴스의 유형 내성하다. 실제 인스턴스에는 구체적인 유형이 있으며이를보고 할 수 있습니다. user the8472의 this comment에서 언급했듯이 유형 삭제 제거 요구는 (T)
으로 캐스팅하거나 new T[]
을 통해 배열을 만들거나 T.class
을 통해 유형 변수 유형에 액세스하려는 바람을 종종 나타냅니다.
이것은 진정한 악몽을 불러올 것입니다. 유형 변수는 실제 인스턴스의 실제 유형과 다른 짐승입니다. 유형 변수는 예 : ? extends Comparator<? super Number>
을 사용하여 하나의 이름을 지정하십시오. 필요한 메타 정보를 제공하는 것은 객체 할당이 훨씬 더 비싸지 않을뿐만 아니라 모든 메소드 호출이 이러한 추가 비용을 부과 할 수 있다는 것을 의미합니다. 실제 클래스와 일반 클래스의 조합에 대해서만 이야기 할뿐만 아니라 또한 와일드 카드로 조합 된 모든 조합 (중첩 된 제네릭 유형조차도)
유형 매개 변수의 실제 유형은 다른 유형 매개 변수를 참조 할 수도 있으므로 형식 검사를 매우 복잡한 프로세스로 전환 할 수 있습니다. 이러한 유형 검사는 생성을 허용하는 경우 모든 유형 변환에 대해 반복 할 필요가 없을뿐만 아니라 그 중에서 하나의 배열은 모든 저장 작업을 반복해야합니다.
성능 문제 외에도 복잡성으로 인해 또 다른 문제가 발생합니다. javac
의 버그 추적 목록이나 Stackoverflow 관련 질문을 살펴보면 프로세스가 복잡 할뿐만 아니라 오류가 발생하기 쉽다는 것을 알 수 있습니다. 현재 javac
의 모든 부 버전에는 일반 유형 서명 일치와 관련된 변경 사항 및 수정 사항이 포함되어있어 수락 또는 거부 될 내용에 영향을줍니다. 변수, 배정 또는 배열 저장소와 같은 본질적인 JVM 작업이 이러한 복잡성의 희생물이되기를 원하지 않으며, 모든 버전에서 합법적인지 또는 아닌지에 대한 아이디어가 다르거 나 갑자기 무엇을 거부했는지 알 수 없습니다. javac
불일치 규칙으로 인해 컴파일 시간.
하위 호환성이 없어지지 않았습니다. 오래된 Java 1.1 프로그램은 링크 된 게시물이 말하는 JRE 8 VM에서 원활하게 실행됩니다. – Tunaki
@Tunaki 내가 틀렸다고 정정 하긴하지만 포워드와의 호환성이 있습니다. 코드는 향후 JVM에서 실행될 것입니다. JVM 버전 X에서 유형 삭제를 제거하면 JVM X + 1에서 제거되므로 코드가 여전히 실행됩니다. – Prime
정확하지는 않습니다. http://stackoverflow.com/questions/4692626/is-jdk-upward-or-backward-compatible – Tunaki