2016-01-01 2 views
5

Я пытаюсь понять, как работает перегрузка в JAVA и пытается понять различные правила перегрузки, которые применяются в случае расширения, автобоксинга и varargs в JAVA. Я не в состоянии понять, что происходит в следующем сценарии:Метод неоднозначен для типа Ошибка

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); 
} 

} 

На данный момент, я получаю ошибку компиляции на третьем вызове метода add говоря The method is ambiguous for the type Error. Почему это так? Каковы правила определения того, какой вызов метода будет работать? Что именно происходит в следующем случае? Я чувствую, что fourth перегруженный метод добавления должен работать. Пожалуйста, помогите мне понять концепцию этого.

+1

Правила указаны в Спецификациях Java Language, и они чрезвычайно длинны и сложны. Помнить их в принципе невозможно, и именно поэтому вы никогда не должны писать код, как указано выше, потому что вы можете почти наверняка ввести ошибки. Я уважаю ваше желание понять, но для этого вам следует прочитать JLS: http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12 –

+0

@JBNizet : Я думаю, что вопрос полностью закончен. Вы можете узнать спецификацию, разбив ее и понять, почему она ломается, а затем никогда не делайте этого снова. – kiltek

ответ

6

Существует 3 этапа перегрузки разрешения метода. На первом этапе не выполняется автоматическое боксирование/распаковка, что означает, что методы, требующие бокса/распаковки переданных параметров, чтобы соответствовать одной из перегруженных версий add, будут учитываться только в том случае, если совпадение не найдено, что не требует бокс/распаковка. Вот почему работают 3 ваших звонка, которые имеют одно точное соответствие. Что касается add(b,c);, см. Ниже, почему это неоднозначно.

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 Я не имел в виду только одну, я имел в виду хотя бы одну. Возможно, я должен перефразировать это. – Eran

+0

Спасибо, поймите – neerajdorle

Смежные вопросы