Come accennato prima, la risoluzione del sovraccarico viene eseguita in fase di compilazione.
Java Puzzlers ha un bell'esempio per questo:
Puzzle 46: il caso del costruttore confuso
Questo puzzle ti presenta due costruttori confusi. Il metodo principale invoca un costruttore, ma quale? L'output del programma dipende dalla risposta. Cosa stampa il programma o è addirittura legale?
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);
}
}
Soluzione 46: caso del costruttore confuso
... Il processo di risoluzione del sovraccarico di Java opera in due fasi. La prima fase seleziona tutti i metodi o costruttori che sono accessibili e applicabili. La seconda fase seleziona il più specifico dei metodi o costruttori selezionati nella prima fase. Un metodo o un costruttore è meno specifico di un altro se può accettare qualsiasi parametro passato all'altro [JLS 15.12.2.5].
Nel nostro programma, entrambi i costruttori sono accessibili e applicabili. Il costruttore
Confusing (Object) accetta qualsiasi parametro passato a Confusing (double []) , quindi
Confusing (Object) è meno specifico. (Ogni double array è un Object , ma non ogni Object è un double array .) Il costruttore più specifico è quindi Confusing (double []) , che spiega l'output del programma.
Questo comportamento ha senso se si passa un valore di tipo double [] ; è controintuitivo se si passa a null . La chiave per comprendere questo puzzle è che il test per quale metodo o costruttore è più specifico non utilizza i parametri effettivi : i parametri che appaiono nell'invocazione. Vengono utilizzati solo per determinare quali sovraccarichi sono applicabili. Una volta che il compilatore ha determinato quali sovraccarichi sono applicabili e accessibili, seleziona il sovraccarico più specifico, utilizzando solo i parametri formali: i parametri che compaiono nella dichiarazione.
Per richiamare il costruttore Confusing (Object) con un parametro null , scrivere new Confusing ((Object) null) . Ciò garantisce che sia applicabile solo Confusing (Object) . Più in generale, per forzare il compilatore a selezionare un sovraccarico specifico, eseguire il cast dei parametri effettivi sui tipi dichiarati dei parametri formali.