Wie bereits erwähnt, wird die Überladungsauflösung zur Kompilierungszeit durchgeführt.
Java Puzzlers hat dafür ein schönes Beispiel:
Puzzle 46: Der Fall des verwirrenden Konstruktors
Dieses Puzzle präsentiert Ihnen zwei verwirrende Konstruktoren. Die Hauptmethode ruft einen Konstruktor auf, aber welcher? Die Ausgabe des Programms hängt von der Antwort ab. Was druckt das Programm oder ist es überhaupt legal?
public class Confusing {
private Confusing(Object o) {
System.out.println("Object");
}
private Confusing(double[] dArray) {
System.out.println("double array");
}
public static void main(String[] args) {
new Confusing(null);
}
}
Lösung 46: Fall des verwirrenden Konstruktors
... Javas Überlastungsauflösungsprozess läuft in zwei Phasen ab. In der ersten Phase werden alle Methoden oder Konstruktoren ausgewählt, auf die zugegriffen werden kann und die anwendbar sind. In der zweiten Phase werden die spezifischsten Methoden oder Konstruktoren ausgewählt, die in der ersten Phase ausgewählt wurden. Eine Methode oder ein Konstruktor ist weniger spezifisch als eine andere, wenn sie Parameter akzeptieren kann, die an die andere übergeben wurden [JLS 15.12.2.5].
In unserem Programm sind beide Konstruktoren zugänglich und anwendbar. Der Konstruktor
Confusing (Object) akzeptiert alle an Confusing (double []) übergebenen Parameter , sodass
Confusing (Object) weniger spezifisch ist. (Jedes Doppelarray ist ein Objekt , aber nicht jedes Objekt ist ein Doppelarray .) Der spezifischste Konstruktor ist daher Confusing (double []) , was die Ausgabe des Programms erklärt.
Dieses Verhalten ist sinnvoll, wenn Sie einen Wert vom Typ double [] übergeben . Es ist nicht intuitiv, wenn Sie null übergeben . Der Schlüssel zum Verständnis dieses Puzzles besteht darin, dass der Test, für den die Methode oder der Konstruktor am spezifischsten ist, nicht die tatsächlichen Parameter verwendet : die im Aufruf angezeigten Parameter. Sie werden nur verwendet, um zu bestimmen, welche Überladungen anwendbar sind. Sobald der Compiler bestimmt hat, welche Überladungen anwendbar und zugänglich sind, wählt er die spezifischste Überladung aus, wobei nur die formalen Parameter verwendet werden: die in der Deklaration angezeigten Parameter.
Um den Konstruktor Confusing (Object) mit einem Nullparameter aufzurufen , schreiben Sie new Confusing ((Object) null) . Dies stellt sicher, dass nur Verwirrend (Objekt) anwendbar ist. Um den Compiler zu zwingen, eine bestimmte Überladung auszuwählen, werden die tatsächlichen Parameter allgemeiner in die deklarierten Typen der formalen Parameter umgewandelt.