2016-01-01 12 views
5

Ich versuche zu verstehen, wie Überladung in JAVA funktioniert und versuchen, verschiedene Überladungsregeln zu verstehen, die im Falle von Erweiterung, Autoboxing und Varargs in JAVA angewendet werden. Ich bin nicht in der Lage zu verstehen, was in dem folgende Szenario passiert:Die Methode ist mehrdeutig für den Typ Fehler

package package1; 

public class JustAClass { 
    public static void add(int a, long b) { 
     System.out.println("all primitives"); 
    } 

    //public static void add(Integer a, long b) { 
    //  System.out.println("Wraper int, primitive long"); 
    //} 

    public static void add(int a, Long b) { 
     System.out.println("Primitive int, Wrapper long"); 
    } 

    public static void add(Integer a, Long b){ 
     System.out.println("All wrapper"); 
    } 

    public static void main(String[] args) { 
     int a = 10; 
     Integer b = 10; 
     long c = 9; 
     Long d = 9l; 

     add(a,c); 
     add(a,d); 
     add(b,c); 
     add(b,d); 
} 

} 

An dieser Stelle ich einen Kompilierungsfehler beim dritten Aufruf des add Methode sagen The method is ambiguous for the type Error. Warum ist das so? Was sind die Regeln um zu bestimmen, welcher Aufruf der Methode funktioniert? Was genau passiert im folgenden Fall? Ich denke, dass fourth überladen Methode hinzufügen sollte funktionieren. Bitte helfen Sie mir, das Konzept dahinter zu verstehen.

+1

Die Regeln sind in den Java-Sprachspezifikationen und sie sind extrem lang und komplex. Sich daran zu erinnern, ist grundsätzlich unmöglich, und deshalb sollten Sie niemals Code wie oben beschrieben schreiben, da Sie fast sicher sein können, Bugs einzuführen. Ich respektiere Ihren Wunsch zu verstehen, aber um das zu tun, sollten Sie die JLS lesen: http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12 –

+0

@ JBNizet : Ich denke, die Frage ist absolut legitim. Sie können die Spezifikation lernen, indem Sie sie brechen und verstehen, warum sie bricht, und dann tun Sie es nie wieder. – kiltek

Antwort

6

Es gibt 3 Stufen, um die Auflösung zu überladen. Die erste Stufe führt kein automatisches Boxing/Unboxing aus, was bedeutet, dass Methoden, die das Boxing/Unboxing der übergebenen Parameter erfordern, um einer der überladenen Versionen von add zu entsprechen, nur berücksichtigt werden, wenn keine Übereinstimmung gefunden wurde, die nicht benötigt wird Boxen/Unboxing. Deshalb funktionieren 3 Ihrer Anrufe, die genau übereinstimmen. Bezüglich add(b,c);, siehe unten, warum es mehrdeutig ist.

add(a,c); // exact match to add(int a, long b) 
    add(a,d); // exact match to add(int a, Long b) 
    add(b,c); // there is no exact match, so at least one of the passed parameters must 
      // be boxed or unboxed. However, by unboxing b to int or boxing 
      // c to Long, each of the three add methods can match, and the 
      // compiler doesn't know which one to prefer 
    add(b,d); // exact match to add(Integer a, Long b) 
+0

@NeerajDorle Ich meinte nicht nur einen, ich meinte mindestens einen. Vielleicht sollte ich das neu formulieren. – Eran

+0

Danke, bringen Sie den Punkt – neerajdorle