문제

일반적인 항아리에 다음 수업이 있습니다.

public class Common 
{
  public Common(List list)
  {
    ...  
  }  
}

그런 다음 생성자 매개 변수를 a에서 변경합니다 List a Collection 다음과 같이 :

public class Common 
{
  public Common(Collection collection)
  {
    ...
  }
}

일반적인 항아리를 재건하고 시스템을 실행하면 NoSuchMethodError 해당 클래스를 다시 컴파일 할 때까지 생성자를 호출 할 때 종속 클래스에서.

생성자가 종속 클래스의 바이트 코드에 어떻게 구속되는지의 선을 따라이 원인의 원인을 몇 가지 아이디어를 얻었지만 100% 확실하지 않습니다.

누군가가 여기서 일어나는 일에 약간의 빛을 비추도록 할 수 있습니까?

업데이트

그 후 빠른 테스트를 수행하고 바이트 코드를 살펴 보았습니다.

Compiled from "Client.java"
public class Client extends java.lang.Object{
public Client();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   new #2; //class ArrayList
   3:   dup
   4:   invokespecial   #3; //Method java/util/ArrayList."<init>":()V
   7:   astore_1
   8:   new #4; //class Common
   11:  dup
   12:  aload_1
   13:  invokespecial   #5; //Method Common."<init>":(Ljava/util/List;)V
   16:  pop
   17:  return

}

Tom이 말했듯이 13 행에서 볼 수 있듯이 정확한 생성자는 컴파일 시간에 묶여 있습니다.

당신은 매일 새로운 것을 배웁니다 :-)

도움이 되었습니까?

해결책

Javac은 컴파일 시간에 호출 할 방법이나 생성자를 정확하게 해결합니다. 이것은 링크 시간에 발생하지 않습니다. 생성자 서명이 변경됨에 따라 연결 단계는 요청 된 메소드를 찾을 수 없으므로 오류가 발생합니다. 생성자에게 제공하여 오류를 고칠 수 있습니다. Collection 다른 하나 List. 나중에 생성자가 Iterable 추가 할 수 있습니다.

일반 유형은 서명의 일부를 형성하지 않으므로 이진 호환성을 유지하면서 변경할 수 있습니다. 매개 변수와 반환 유형은 모두 메소드 서명의 일부를 형성합니다 (공분산 반환은 합성 브리지 방법을 생성합니다).

이있다 JLS의 멋진 큰 섹션 이진 호환 변경을 구성하는 요소를 정확하게 정의합니다.

다른 팁

올바른 목록 및 컬렉션 클래스를 가져오고 있습니까? 즉 java.util.List 그리고 java.util.Collection?

라이브러리 버전에 문제가 될 수 있다고 생각합니다. 같은 맥락에서 다른 곳에 다른 버전의 커먼즈 라이브러리가 없다고 확신합니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top