La risoluzione del costruttore di MyClass
viene eseguita al momento della compilazione. Quando il compilatore compila il codice del costruttore Test
, non sa cosa sia in realtà T
, sa solo che è garantito essere un Map<String, String>
, quindi non può fare nient'altro che legare la chiamata del costruttore al costruttore che prende un Map
. La conoscenza che nel codice T
è un TreeMap
è presente solo all'interno del corpo del metodo main
, non all'esterno. Si consideri, ad esempio, cosa succederebbe se aggiungessi un secondo chiamante del costruttore Test
che effettivamente supera uno HashMap
.
generici Java funzionano in modo tale che il codice di un metodo generico viene compilata una sola volta per tutti i possibili valori dei parametri generici (e presente solo una volta nel codice byte), non è come in altre lingue una copia del metodo generico per ogni tipo generico.
In generale, non è possibile in Java per lasciare una singola chiamata di metodo/costruttore nel codice effettivamente chiamare diversi metodi/costruttori in fase di esecuzione a seconda del tipo di argomenti. Questo è possibile solo per le chiamate di metodo a seconda del tipo di runtime dell'oggetto chiamato (associazione dinamica con metodi sovrascritti).
Il sovraccarico (quello che hai qui) funziona solo in fase di compilazione osservando il tipo statico degli argomenti.
La soluzione tipica per questa situazione consiste nell'utilizzare un controllo instanceof SortedMap
all'interno del costruttore di MyClass
. Un'altra possibile (più elegante) soluzione è il pattern visitor, ma funziona solo con le classi che sono state preparate per questo (quindi non con le istanze Map
se non le si avvolge in una classe propria).
fonte
2015-01-17 14:26:20
Come è possibile che il compilatore non sappia che tipo 'T' sia effettivamente? Lo sto costruendo come un 'TreeMap' (capirò il comportamento se il costruttore è stato invocato passando un oggetto dichiarato come' Map' che era veramente un 'TreeMap', ma non è questo il caso) –
Oh, mi aspettavo per generare codice diverso per diverse versioni di 'T' nello stesso metodo generico. Suppongo che Java non sia C++. Grazie per la risposta, ora è chiaro. –