리플렉션을 사용하여 정수 목록에 Double을 추가 할 수있는 이유
이 코드가 예외없이 실행되는 이유는 무엇입니까?
public static void main(String args[]) {
List<Integer> a = new ArrayList<Integer>();
try {
a.getClass()
.getMethod("add", Object.class)
.invoke(a, new Double(0.55555));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(a.get(0));
}
제네릭은 컴파일 타임입니다. 런타임시 ArrayList
추가 검사없이 일반 . 당신이 목록에 요소를 추가하는 반사를 사용하여 안전 점검을 우회하고 있기 때문에, 아무는 것을 방지 할 수 없습니다 Double
당신의 내부에 저장되지 List<Integer>
. 당신이 한 것처럼
List<Integer> list = new ArrayList<Integer>();
List rawList = list;
rawList.add(new Double(2.5));
목록에서 런타임에 유형 검사를 구현하려면 다음을 사용하십시오.
List<Integer> checkedList = Collections.checkedList(list, Integer.class);
유형 삭제로 인해-제네릭에 대한 런타임 검사가 없으며 컴파일 중에 유형 매개 변수가 제거됩니다. Java generics-type erasure-언제, 무슨 일이 발생합니까 ?
당신은 놀랄 수 있지만, 당신은을 추가 반사를 사용할 필요가 없습니다 Double
A를 List<Integer>
:
List<Integer> a = new ArrayList<Integer>();
((List)a).add(new Double(0.555));
그 이유는 유형 삭제입니다 . 이것이 Integer
s 목록이라는 사실 은 JVM이 아니라 컴파일러에 알려져 있습니다.
코드를 컴파일하면 List<Integer>
된다 List<Object>
오류없이 반사 기반의 코드 완성을 허용.
자신의 코드에는 이것이 작동하는 이유에 대한 강력한 힌트가 있습니다.
a.getClass()
.getMethod("add", Object.class) // <<== Here: Object.class, not Integer.class
.invoke(a, new Double(0.55555));
또한 반사없이 캐스팅을 창의적으로 사용하여 동일한 악한 결과를 얻을 수 있습니다. 이 모든 것은 유형 삭제로 Java 제네릭을 구현하기로 한 설계 결정의 결과입니다.
제네릭은 자바가 제공하는 컴파일 시간 기능 일뿐입니다. 제네릭 이전에는 컴파일 타임에 컬렉션에서 가져온 'Object'인스턴스가 실제로 예상 한 유형인지 확인할 수있는 방법이 없었습니다. 우리는 코드에서 사용할 수 있도록 객체를 적절한 유형으로 캐스팅해야 할 것이며, 이는 런타임에만 JVM이 ClassCastException
. 컴파일 타임에는 이것으로부터 우리를 보호 할 것이 없었습니다.
Generics는 컴파일 타임에 컬렉션에서 유형 검사를 시행하여이 문제를 해결했습니다. 그러나 제네릭에 대한 또 다른 중요한 점은 런타임에 존재하지 않는다는 것입니다. List 또는 Map과 같은 유형 컬렉션을 포함하는 클래스를 디 컴파일하고 여기에서 생성 된 Java 소스를 보면 일반 컬렉션 선언을 찾을 수 없습니다. 리플렉션 코드는 런타임에 작동하고 컴파일 시간을 포함하지 않으므로 예외가 발생하지 않습니다. 일반적인 넣기 또는 추가 작업으로 컴파일 타임에 동일한 작업을 시도하면 컴파일 타임 오류가 발생합니다.
'IT Share you' 카테고리의 다른 글
Oracle JDK 64 비트를 사용하는 Ubuntu 13.04에서 Eclipse Indigo가 충돌하는 이유는 무엇입니까? (0) | 2020.11.29 |
---|---|
Xcode 5에서 앱의 번들 식별자를 변경하는 방법은 무엇입니까? (0) | 2020.11.29 |
Angular 경로에 대한 htaccess 리디렉션 (0) | 2020.11.29 |
"adb shell dumpsys alarm"출력을 읽는 방법 (0) | 2020.11.29 |
컴파일 타임에 C ++ 클래스의 크기를 인쇄 할 수 있습니까? (0) | 2020.11.29 |