목록 <정수>에 예기치 않은 추가 문자열

존 :

나는 그것이 출력으로 컴파일러 핸들이 다음 코드의 방법을 이해하지 않는 테스트를 내가 오류를 기대하고있다.

List<Integer> b = new ArrayList<Integer>();
List a = b;
a.add("test");
System.out.println(b.get(0));

나는 누군가가 나에게 말할 수있는 기대했다 정확한 I 출력을 이해할 수 있도록 컴파일러는 코드를 실행할 때 통과 단계를. 나의 현재 이해는 즉 :

  1. 인수 유형을 지원하는 추가 방법에있는 경우 컴파일 시간 동안 컴파일러 점검 목록 입니다 클래스 추가 (개체 E) 원시 타입의 등.
  2. 그러나 런타임 중에 실제 개체에서 추가 (개체 E)를 호출하려고 목록 <정수> 실제 개체가-원시 입력하지 않고 대신 메소드 보유하고이 방법을 보유하지 않는 추가 (정수 전자) .

실제 개체에서의 더 추가 (개체 E) 방법이없는 경우 목록 <정수> 어떻게 여전히 어떻게 든 정수의 목록에 문자열을 추가합니까?

레이 톨 :

당신은 아주 가까이 있습니다. 컴파일 시간 검사는 모두 밖으로 이동 :

a유형 인 List콜 있도록

a.add("test");

밖으로 패닝. b(컴파일 시간)입니다 입력 ArrayList<Integer>그래서

b.get(0)

뿐만 아니라 아웃 체크한다. 점을 유의 검사가 변수 만의 컴파일 타임 유형에 대해 만들어집니다 . 컴파일러가 볼 때 a.add("test")그것은 않습니다 하지 변수에 의해 참조되는 객체의 실행 시간 값을 알고있다 a. 제어 흐름 유형 분석을 잡을 수 있지만 일반적으로, 정말 할 수는 없습니다 (이에 대한 이론적 컴퓨터 과학의 결과있다) 많은 같은 것을. 타이프 라이터와 같은 언어는 컴파일 시간에 놀라운 일을 할 수있다.

지금 당신은 실행 시간에 같은 일을 점검 할 수 있다고 가정 할 수 있습니다. 아아, 자바 그들은 할 수 없습니다. 자바는 일반적인 유형을 삭제합니다. 피투성이 자세한 내용은 Java 유형의 삭제에 관한 기사를 찾아보십시오. 는 TL; DR은이다 List<Integer>컴파일시 원시된다 List런타임한다. (다른 언어가있다하더라도!) JVM은 "구체화"제네릭 할 수있는 방법이 없었다 그래서 제네릭이 도입되었을 때, 결정은 자바 그냥 일반적인 유형을 지울 것이라고 하였다. 그래서 실행 시간에 코드에서 어떤 유형의 문제가 없다.

의 컴파일 된 코드를 살펴 보자 :

   0: new           #2                  // class java/util/ArrayList
   3: dup
   4: invokespecial #3                  // Method java/util/ArrayList."<init>":()V
   7: astore_1
   8: aload_1
   9: astore_2
  10: aload_2
  11: ldc           #4                  // String test
  13: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
  18: pop
  19: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
  22: aload_1
  23: iconst_0
  24: invokeinterface #7,  2            // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
  29: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
  32: return

여기에는 런타임 유형 검사가 없다는 것을 직접 볼 수 있습니다. 따라서, 귀하의 질문에 대한 전체 (그러나 겉으로는 경박 한) 답은의 유형에 따라 컴파일시에 자바 만 검사 유형이다 변수 (컴파일 타임에), 그러나 제네릭 형식 매개 변수를 삭제하고 코드는 그들없이 실행됩니다.

추천

출처http://43.154.161.224:23101/article/api/json?id=181413&siteId=1