2017-02-05 17 views
7

Этого вопрос может быть похож на Java overload confusionМетод перегрузка: Единственный параметр против параметров переменного

Я читал книгу, и есть тема о перегрузке методы, из которого компилятор не может быть в состоянии решить Вызываемый метод. В примере в книге используется перегруженный метод с двумя параметрами (int, double) и (double, int). Вызов этого метода, например overloadedTwoParam (4, 5), вызовет ошибку компилятора, поскольку int может быть передано в double. Мой вопрос здесь в том, почему компилятор может решить, какой метод будет вызываться, если мой параметр только один?

public class Test { 

    public static void main(String[] args) { 
     Test t = new Test(); 
     t.overloadedSingleParam(1); //this is working 
     t.overloadedTwoParam(4, 5); //this is NOT working 
    } 

    void overloadedSingleParam(double a) { 
     // do something here.. 
    } 

    void overloadedSingleParam(int a) { 
     // do something here.. 
    } 

    void overloadedTwoParam(double a, int b) { 
     // do something here.. 
    } 

    void overloadedTwoParam(int a, double b) { 
     // do something here.. 
    } 
} 
+0

У вас нет ответа на ваш вопрос в ответе? – CKing

+0

у вас есть метод, который принимает один параметр 'int'. –

+0

@jackjay да, но int может быть передан в двойной параметр, почему java все еще может его решить? – fuzzy28

ответ

2

Интуиция и ответ CKing хороши.
Я свяжусь с JLS.

Общая идея: компилятор выбирает наиболее специфический метод ... если он нашел его.

В заявлении JLS говорится, что неформальная интуиция заключается в том, что один метод более конкретный, чем другой, если любой вызов, обработанный первым методом, может быть передан другому, без ошибки типа компиляции. Это короткая версия.
В ссылке JLS, на которую делается ссылка, указаны все правила, применяемые компилятором для выбора наиболее конкретного метода.

Возможно, что никакой метод не является наиболее конкретным, поскольку существуют два или более метода, которые являются максимально конкретными. В этом случае возникает ошибка компиляции, указывающая, что вызов метода неоднозначен.


В первом сценарии компиляция хорошо, как у вас есть уникальный максимально конкретный метод:

Test t = new Test(); 
t.overloadedSingleParam(1); 

... 
void overloadedSingleParam(double a) { 
    // do something here.. 
} 
void overloadedSingleParam(int a) { 
    // do something here.. 
} 

void overloadedSingleParam(int a) является точным соответствием, как мы оба int в качестве формального параметра метода и эффективного параметра ,
В то время как overloadedSingleParam(double a) требует неявного преобразования от int до double.

Так overloadedSingleParam(double a) не имеет значения, кроме void overloadedSingleParam(int a), когда значение int передается как аргумент.
Итак, компилятор выбирает void overloadedSingleParam(int a), и компиляция выполнена успешно.


Во втором случае дело обстоит иначе: вы падаете в случае отсутствия одного метода является более точным, чем другой один:

Test t = new Test(); 
t.overloadedTwoParam(4, 5); 

... 
void overloadedTwoParam(double a, int b) { 
    // do something here.. 
} 

void overloadedTwoParam(int a, double b) { 
    // do something here.. 
} 

Вы можете проверить это с неформальной интуицией:

  • overloadedTwoParam((double)3, 4) прилагается к void overloadedTwoParam(int a, double b) не компилируется.

  • overloadedTwoParam(3, (double)4) прилагается к void overloadedTwoParam(double a, int b) также не скомпилируется.

Следовательно, возникает ошибка компиляции.

7

Мой вопрос вот почему компилятор в состоянии решить, какой метод будет вызываться, если мой параметр только один

Когда дело доходит до одного параметра, компилятор может видеть, что существует метод, который принимает int, поэтому нет путаницы в отношении того, какой метод следует вызывать. Даже если вы удалите метод, который принимает один int, компилятор все равно сможет вызвать метод, который принимает один double, поскольку здесь нет никакой двусмысленности. (int может быть повышен до double)

Когда речь идет о других методах, которые чередовать int и double параметров компилятор не хочет брать на себя ответственность за принятие решения, следует ли продвигать первый параметр в double или второй параметр до double.