2015-08-12 22 views
6

Ho appena scritto un po 'di codice con la seguente struttura:Perché questo non produce un'ambiguità?

public void method(int x) { 
    //... 
} 

public void method(int x, String... things) { 
    //... 
} 

Sono rimasto piuttosto sorpreso che questo compilato, e che se ho invocato

method(3); 

allora sarebbe scegliere il primo. Ovviamente questo è in un certo senso il naturale da selezionare, ma se il primo metodo non esistesse, sarebbe un modo ragionevole di invocare il secondo (con un array varargs vuoto). Quindi sicuramente dovrebbe essere considerato ambiguo e produrre un errore in fase di compilazione?

Oppure si tratta di un caso speciale?

Sembra sbagliato trattarlo come tale, perché significa che l'aggiunta di un nuovo metodo potrebbe rompere il codice esistente, e questo non è uno stato di cose molto felice.

(chissà solo che quello che si finirebbe invocando se il primo sono stati aggiunti come nuovo metodo di una sottoclasse che contiene il secondo ...)

+0

Hai chiamato un metodo con 1 parametro, perché chiamerebbe quello con 2 necessario? – loli

+2

@loli perché non ce n'è uno con due necessari. Il secondo ha un parametro varargs, il che significa che la parte 'String ...' può prendere qualsiasi numero di argomenti, incluso zero. –

+0

@ chiastic-security Ah non sapevo che fosse l'equivalente Java, pensavo che tu avessi scritto ... perché eri troppo pigro per trovare [] sulla tastiera i metodi varag – loli

risposta

10

Secondo Chapter 15 della specifica linguaggio Java, la ricerca di un metodo applicabile è fatto in tre fasi.

La prima fase (§15.12.2.2) esegue la risoluzione di sovraccarico senza consentire la conversione di boxing o unboxing o l'uso di richiamo del metodo di variabile arity. Se non viene trovato alcun metodo applicabile durante questa fase, l'elaborazione continua fino alla seconda fase.

Quindi, il primo metodo è già considerato applicabile nella prima fase. Il resto delle fasi viene saltato; il metodo String ... sarebbe considerato solo nella terza fase:

La terza fase (§15.12.2.4) consente di combinare l'overloading con metodi di aritmetria variabile, boxing e unboxing.

0

Il tipo di argomento del primo metodo è

int x 

i tipi di argomenti del secondo metodo sono

int x, String[] things 

Pertanto i due metodi fare non hanno le stesse s ignoranza e non c'è ambiguità. @Glorfindel spiega come Java decide quale metodo invocare, ma se si desidera richiamare il secondo metodo senza alcun things, è possibile passare in un array vuoto.

method(6, new String[0]); 
Problemi correlati