Come accennato prima la risoluzione di sovraccarico viene eseguita in fase di compilazione.
Java Puzzlers ha un bel esempio per questo:
Puzzle 46: Il caso del costruttore Confondere
Questo puzzle si presenta con due costruttori di confusione. Il metodo principale richiama un costruttore, ma quale? L'output del programma dipende dalla risposta. Che cosa stampa il programma o è 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 Confondere
... processo di risoluzione di 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 lo più specifico dei metodi o dei costruttori selezionati nella prima fase. Un metodo o costruttore è meno specifico di rispetto a 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 Confondere (Object) accetta qualsiasi parametro passato Confondere (double []), così Confondere (Object) è meno specifico. (Ogni doppio array è un oggetto , ma non ogni oggetto è un doppio array.) Il costruttore più specifica è quindi Confondere (double []), il che spiega l'output del programma.
Questo comportamento ha senso se si passa un valore di tipo double []; è controintuitivo se si passa nullo. La chiave per comprendere questo enigma è che il test per quale metodo o costruttore è più specifico non utilizza i parametri effettivi: i parametri che appaiono nel richiamo. Vengono utilizzati solo per determinare quali sovraccarichi sono applicabili. Una volta che il compilatore determina quali sovraccarichi sono applicabili e accessibili, seleziona il sovraccarico più specifico, utilizzando solo i parametri formali: i parametri che appaiono nella dichiarazione.
di avviare la Confondere (Object) costruttore con un parametro nullo, scrivere nuovo Confondere ((Object) null). Ciò garantisce che solo Confusione (oggetto) sia applicabile.Più in genere, per forzare il compilatore a selezionare un sovraccarico specifico, trasmettere i parametri effettivi ai tipi dichiarati dei parametri formali.
fonte
2009-10-15 13:47:22
Puoi spiegare le specifiche che hai citato per favore. Le due frasi sembrano contraddirsi l'una con l'altra. L'esempio sopra utilizza i metodi di istanza, tuttavia il metodo invocato non è chiaramente determinato in fase di esecuzione. –
@Alex Worden: il tipo di tempo di compilazione ** dei parametri del metodo ** viene utilizzato per determinare la firma del metodo da chiamare, in questo caso 'foo (Object)'. In fase di esecuzione, la classe dell'oggetto ** il metodo viene richiamato ** determina quale implementazione di quel metodo viene chiamata, tenendo conto che potrebbe trattarsi di un'istanza di una sottoclasse del tipo dichiarato che sovrascrive il metodo. –