IT Share you

리플렉션을 사용하여 정수 목록에 Double을 추가 할 수있는 이유

shareyou 2020. 11. 29. 12:38
반응형

리플렉션을 사용하여 정수 목록에 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-언제, 무슨 일이 발생합니까 ?

당신은 놀랄 수 있지만, 당신은을 추가 반사를 사용할 필요가 없습니다 DoubleA를 List<Integer>:

List<Integer> a = new ArrayList<Integer>();
((List)a).add(new Double(0.555));

그 이유는 유형 삭제입니다 . 이것이 Integers 목록이라는 사실 은 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 소스를 보면 일반 컬렉션 선언을 찾을 수 없습니다. 리플렉션 코드는 런타임에 작동하고 컴파일 시간을 포함하지 않으므로 예외가 발생하지 않습니다. 일반적인 넣기 또는 추가 작업으로 컴파일 타임에 동일한 작업을 시도하면 컴파일 타임 오류가 발생합니다.

참고 URL : https://stackoverflow.com/questions/20300828/why-can-a-double-be-added-to-a-list-of-integers-using-reflection

반응형