2013-08-01 17 views
12

La JVM decide quale metodo sovraccarico chiamare al momento della compilazione. Ho un esempio:In che modo JVM trova il metodo (parametro con la corrispondenza più simile) da chiamare in caso di sovraccarico della funzione

public class MainClass{ 

    public static void go(Long n) {System.out.println("takes Long ");} 
    public static void go(Short n) {System.out.println("takes Short ");} 
    public static void go(int n) {System.out.println("takes int ");} 

    public static void main(String [] args) { 
    short y = 6; 
    long z = 7; 
    go(y); 
    go(z); 
    go((Short)y); 
    } 
} 

Secondo la mia comprensione, si deve stampare la seguente:

takes Short 
takes Long 
takes Short 

... ma l'uscita reale è:

takes int 
takes Long 
takes Short 

Tuttavia se ho le seguenti tre funzioni:

public static void go(Integer n) {System.out.println("takes Integer");} 
public static void go(Long n) {System.out.println("takes Long ");} 
public static void go(Short n) {System.out.println("takes Short ");} 

... e chiamare utilizzando:

int a= 10; and go(i); //output : takes Integer. 

... perché c'è lì la differenza per short e int?

+0

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.4 – kosa

+0

Eventuali duplicati http://stackoverflow.com/ q/6268157/2087187 – EProgrammerNotFound

risposta

18

Vedi JLS Section 15.12.2, per le regole compilatore segue per determinare il metodo da invocare. Il compilatore sceglie sempre il metodo più specifico in caso di sovraccarico dei metodi:

Possono esserci più di un metodo di questo tipo, nel qual caso viene scelto quello più specifico. Il descrittore (signature plus return type) del metodo più specifico è quello utilizzato in fase di esecuzione per eseguire la spedizione del metodo.

compilatore prima tenta di risolvere il metodo senza boxe o unboxing come citato c'è:

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

Enfasi mia.

Così, nel codice 1 ° , dal momento che breve può essere usato come argomento per il parametro di tipo int .Il compilatore non utilizzerà il metodo con il parametro Short, poiché ciò richiede il pugilato. Mentre in caso di lungo tipo, dal momento che non può essere utilizzato come argomento per il tipo int, va per boxing a Long. Ricorda L'allargamento è preferito su Boxing.

Nella 2 ° , non c'è altra via che la boxe int a Integer. Quindi, chiama metodo con il parametro Integer.

8

La JVM non la trova affatto. Il compilatore lo fa. Si sceglie il più specifico metodo di , seguendo le regole nella JLS section 15.12.2.5:

Se più di un metodo membro è accessibile e applicabile ad una chiamata di metodo, è necessario scegliere uno di fornire il descrittore per la corsa data di spedizione del metodo. Il linguaggio di programmazione Java utilizza la regola per scegliere il metodo più specifico.

L'intuizione informale è che un metodo è più specifico di un altro se qualsiasi chiamata gestita dal primo metodo può essere passata all'altro senza un errore di tipo in fase di compilazione.

... (regolamento completo) ...

+2

+1 non solo il nome e i parametri devono essere una corrispondenza esatta, ma deve essere anche il tipo restituito. Se A chiama B e cambi il tipo di ritorno di un metodo in B senza ricompilare A, non troverà il metodo in fase di runtime. –

1

Poiché upcasting a int era in versione 1.0 di Java e auto-boxing è stato aggiunto nella versione 5.0. La modifica del comportamento interromperebbe il codice scritto per la versione precedente di Java.

+0

Non è "upcasting" --- è una "conversione allargata". Ma per il resto un buon punto, +1. –

+1

@MarkoTopolnik. Beh, la risposta sembra una copia incolla della risposta accettata dal duplicato pubblicato per questa domanda. Quindi, l'errore è in * Source *. lol;) –

+0

@RohitJain Oops, grazie per averlo verificato! E sappiamo cos'è il plagio ... –

0

L'ampliamento avviene prima della boxe (se presente). Quindi, short diventerà int e chiameremo tali metodi.

Inoltre, non direttamente pertinenti con questa domanda, ma punto interessante: non è possibile box e ampliare cioè short non può diventare Integer

0

Java cerca la corrispondenza più vicina prima. Si cerca di trovare il seguente:

  1. corrispondenza esatta per tipo
  2. corrispondenza di un super tipo di classe
  3. Conversione in una più grande tipo primitivo
  4. Conversione in un auto in scatola tipo
  5. varargs