2016-04-20 10 views
0

Ich bin sehr überrascht, warum Ausgabe ist sehr unterschiedlich von dem, was ich erwarte, habe ich zwei überladene Methoden, eine mit einer Zeichenfolge und die andere ein Objekt als Parameter, beim Aufrufen dieser Methode mit NULL-Parameter, Ausgabe druckt nur "String" und keine Methode mit Objekt als Parameter aufrufen.Unerwartete überladene Methode Compiler Auswahl mit Null-Parameter

Warum wählt Java die Methode mit String als Parameter aus? Wie bestimmt Java, welche überladene Methode aufgerufen werden soll?

class TestingClass { 
    public void test(String s) { 
     System.out.println("String"); 
    } 

    public void test(Object o) { 
     System.out.println("Object"); 
    } 

    public static void main(String[] args) { 
     TestingClass q = new TestingClass(); 
     q.test(null); 
    } 
} 
+0

Wiederholen Sie es nach mir. Das Überschreiben geschieht nur in abgeleiteten Klassen und auch nur dann, wenn die Methodenparameter gleich sind. Der Rückgabetyp darf kovariant sein. – Madhusudhan

+0

Ein ausführlicherer Text erklärt, was Eran gesagt hat. [Nach Denis Antwort suchen] (http://stackoverflow.com/questions/1572322/overloaded-method-selection-based-on-the-parameters-real-type) –

Antwort

2

In diesem Code gibt es kein Überschreiben, nur Überladen der Methode. Wenn der Compiler auswählen muss, welche der beiden test-Methoden ausgeführt werden soll (da null an beide übergeben werden kann), wählt er diejenige mit dem spezifischeren Argumenttyp - test(String s) - String ist spezifischer als Object, da es sich um eine Unterklasse handelt von Object.

kann der andere Methode aufgerufen werden:

q.test((Object) null); 
+0

Wie Zeichenfolge ist spezifischer als Object? –

+1

@ jk2praj Eine Unterklasse ist spezifischer als ihre Oberklasse. So ist der Begriff "spezifischer" in der JLS definiert. – Eran

+1

Weil String eine Unterklasse von Object ist. Wenn die Klassen jedoch nicht durch die Vererbungshierarchie verknüpft sind, erhalten Sie einen Kompilierzeitfehler – Madhusudhan

0

Ohne das Hinzufügen einer möglichen neuen Antwort, lassen Sie mich schlagen Sie Ihren Code zu erweitern, wie folgt,

public class Overload { 

    public static void main(String[] args) { 
     new Overload().test(null); 
    } 

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

    public void test(Object o) { 
     System.out.println("Object"); 
    } 

    public void test(Integer s) { 
     System.out.println("Integer"); 
    } 

} 

Kommentieren Sie irgendeine von Object oder Integer-Version sehen Sie es für sich. Die Antwort wird bereits von anderen gegeben.