Ändern eines Konstruktor param Typ Pausen Klasse in einem anderen Gefäß
-
05-07-2019 - |
Frage
Ich habe die folgende Klasse in einem gemeinsamen Gefäß:
public class Common
{
public Common(List list)
{
...
}
}
ich dann den Konstruktor Parameter aus einer List
zu einem Collection
wie folgt ändern:
public class Common
{
public Common(Collection collection)
{
...
}
}
Der Wiederaufbau der gemeinsamen Gefäß und das System läuft verursacht eine NoSuchMethodError
in jeder Klasse abhängig, wenn es den Konstruktor aufruft, bis ich diese Klasse neu kompilieren.
Ich habe ein paar Ideen bekommen, was dies verursacht, entlang den Linien, wie der Konstruktor in der Bytecode der abhängigen Klasse gebunden ist, aber ich bin nicht 100% sicher.
Bitte kann jemand etwas Licht auf vergossen, was hier vor sich geht?
Update
Ich habe einen schnellen Test anschließend getan und einen Blick auf die Bytecode genommen:
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
}
Wie Tom sagte, und wie Sie in Zeile 13, die genaue Konstruktor wird bei der Kompilierung gebunden sehen können.
Sie lernen jeden Tag etwas Neues: -)
Lösung
javac löst genau, welche Methode oder Konstruktor bei der Kompilierung zu rufen. Dies tritt nicht beim Linken. Da der Konstruktor Signatur geändert hat, kann der Vernetzungsschritt nicht die gewünschte Methode finden und damit einen Fehler wirft. Sie können den Fehler beheben, indem Sie auf Konstrukteuren bietet - eine, die ein Collection
die anderen List
nimmt. Später wurde ein Konstruktor eine Iterable
Aufnahme hinzugefügt werden.
Hinweis, generische Typen Teil der Signatur nicht bilden, so dass diejenigen, kann während noch halten Binärkompatibilität geändert werden. Beide Parameter und Rückgabetypen sind Teil der Signatur für Verfahren (kovarianten kehrt verursachen synthetische Brücke Methoden erstellt werden).
Es ist ein schönen großen Abschnitt in der JLS definieren, genau das, was binärkompatibel Änderungen darstellt.
Andere Tipps
importieren Sie die richtige Liste und Sammlung Klassen? das heißt java.util.List
und java.util.Collection
?
Ich denke, es ist ein Problem mit der Bibliothek in der Version sein könnte. Sind Sie sicher, dass es nicht eine andere Version der commons Bibliothek woanders im gleichen Kontext ist?