생성자 매개 변수 유형 변경 다른 항아리에서 클래스를 중단합니다.
-
05-07-2019 - |
문제
일반적인 항아리에 다음 수업이 있습니다.
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
?
라이브러리 버전에 문제가 될 수 있다고 생각합니다. 같은 맥락에서 다른 곳에 다른 버전의 커먼즈 라이브러리가 없다고 확신합니까?