2010-06-13 15 views
16

Ho il seguente codice:
Qual è la spiegazione di questo codice java?

public class Main { 
    public void method(Object o) 
    { 
      System.out.println("Object Version"); 
    } 
    public void method(String s) 
    { 
      System.out.println("String Version"); 
    } 
    public static void main(String args[]) 
    { 
      Main question = new Main(); 
      question.method(null);//1 
    } 
} 

Perché il risultato è "String Versione"? e perché c'è un errore del compilatore se il primo metodo accetta un oggetto StringBuffer?
Un altro caso: se il primo metodo prende un oggetto StringBuffer e scrivo question.method("word"); il risultato sarà "Versione stringa". Perché ? perché non c'è nessun errore del compilatore?

+0

Curioso. Mi sarei aspettato un compilatore brontolare lì, ma forse il fatto che ci sia una relazione di tipo tra le due classi di argomenti ('String' è il più specifico) cambia le cose e questo è un caso nel JLS? Il caso 'StringBuffer' è facile, dato che è decisamente ambiguo. –

+1

@third question: Ovviamente non avrai un errore. Stai passando una stringa, quindi sarà ovviamente invocato il metodo con il parametro String. Non c'è nulla da cui il compilatore possa confondersi. – someguy

risposta

23

La specifica JAVA dice che in casi come questo, verrà chiamata la funzione più specifica. Poiché String è un sottotipo di Object, verrà chiamato il secondo metodo. Se si modifica Oggetto in StringBuffer - non esiste un metodo specifico poiché StringBuffer non è un sottotipo di String e viceversa. In questo caso il compilatore non sa quale metodo chiamare - quindi l'errore.

1

Quando si guarda all'altro caso:

pacchetto com.snamellit;

public class Main { 
    public void method(Object o) { 
     System.out.println("Object Version"); 
    } 

    public void method(String s) { 
     System.out.println("String Version"); 
    } 

    public static void main(String args[]) { 
     Main question = new Main(); 
     question.method("word"); 
    } 
} 

Se il primo metodo tqkes uno StringBuffer e la seconda una stringa, non c'è confusione possibile, come "parola" è una stringa e non uno StringBuffer.

In Java l'identità di una funzione/metodo dipende da 3 cose: il nome, il tipo dei parametri (ovvero la firma dell'argomento) e il classloader. Poiché entrambi i tipi hanno una firma di argomento diversa, il compilatore può facilmente scegliere quello giusto e non genera un errore.

+0

Ma genera _un errore: potresti elaborare, Peter? –

+0

grazie Peter.Penso che si verifichi un errore del compilatore poiché "word" è un valore StringBuffer valido. –

+2

No, è una stringa, non un StringBuffer. StringBuffers sono il cugino mutabile di Stringhe, che sono immutabili e quindi un ottimo modello per stringhe letterali. Un uomo saggio ha detto: "In caso di dubbio, provalo": System.out.println ("word" .getClass(). GetName()) stamperà java.lang.String. –

Problemi correlati