2014-12-02 10 views
5

I haben die folgenden 2 Verfahren in einer Klasse überlastet:Method Überlastung und Leiten null

public class Test{ 

    public static void main(String []args) throws ParseException{ 
     Test t = new Test(); 
     t.testMethod(null); 
    } 

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

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

Wenn ich die Methode aufrufen testMethod es "String" drucken.

Wenn ich noch eine überladene Methode hinzufügen:

public void testMethod(StringBuilder sb){ 
    System.out.println("String"); 
} 

Es wirft mich Compiler-Fehler: The method testMethod is ambigous for type Test ..

All dies geschieht, wenn ich die Methode mit null

Meine Fragen berufen sind:

  1. Warum druckt String und nicht Objekt ?
  2. Warum ist beim Hinzufügen der dritten Methode ein Kompilierungsfehler aufgetreten?
+0

Abgesehen von Ihrer spezifischen Frage, schlage ich vor, dass Sie vermeiden, eine Signatur mit einem Objektparm und andere mit einem bestimmten Datentyp zu haben. Es mag schön sein, es als Auffangbecken zu haben, aber normalerweise lauern sie Fallen. –

Antwort

1

Warum druckt String und nicht Objekt?

der Java-Compiler wählt die Methode mit dem spezifischsten oder dest generic Argument. Seit Object ist die Superklasse aller Klassen (einschließlich String), String Klasse ausgewählt.

Warum ist beim Hinzufügen der dritten Methode ein Kompilierungsfehler aufgetreten?

Seit String und StringBuilder unter Object sind, findet der Compiler den Aufruf mehrdeutig da sowohl String und StringBuilder kann null akzeptieren, schlägt der Compiler, welche Methode zu bestimmen, daher rufen Sie Fehler erhalten während der Kompilierung.

Wenn Sie die gleiche Sache mit IOException und FileNotFoundException statt String und StringBuilder versuchen, werden Sie feststellen, dass FileNotFoundException gerichtet, da sie am wenigsten generisch ist.

3

Die Methodenauflösung funktioniert, indem die Methode spezifisch ausgewählt wird, die für die angegebenen Argumente anwendbar ist. In Ihrem ersten Fall ist String "spezifischer" als Object (da es eine Unterklasse von Object ist) und so wird die String Methode gewählt.

Wenn Sie eine andere Methode hinzufügen, die eine StringBuilder nimmt sowohl das und die String Verfahren sind gleichermaßen „spezifisch“ (sie beide direkte Subklassen von Object sind), so gibt es eine Mehrdeutigkeit darüber, welche der Fehler daher gewählt werden sollte, .

0

In case1 String erbt von Object, sie sind in der Vererbungskette, null entspricht beiden, Compiler wählt einen spezifischeren Typ - String.

Wenn 2 String und StringBuilder nicht in der Vererbungskette sind, kann der Compiler keinen spezifischeren Typ auswählen.

Einzelheiten zur überladenen Methodenauflösung sind in JLS 15.12.2 beschrieben.