перегрузка метода, как решить, какая версия перегруженного метода в приведенном ниже случае - PullRequest
0 голосов
/ 21 января 2020

В java у меня есть 2 метода, которые перегружены, и один из них является основным методом, поэтому из основного метода я вызываю перегруженный метод.

public class Test {
public static void main(String[] args) throws IOException {
    doSomething(null);
}
private static void doSomething(Object o) {
    System.out.println("method with Object in signature is called.");
}
private static void doSomething(String s) {
    System.out.println("method with String in the signature is called.");
}
}

Здесь, когда я запускаю этот код java , он вызовет метод doSomething (String s) и напечатает метод

с именем String в сигнатуре.

Я думаю, что он вызовет doSomething (Object о) метод, но этого не произойдет.

Так может ли кто-нибудь объяснить мне это более подробно, почему это произошло и как?

Спасибо.

Ответы [ 3 ]

9 голосов
/ 21 января 2020

С JLS 15.12.2.5 (выделение добавлено):

Если более одного метода-члена доступны и применимы к вызову метода, необходимо выбрать один предоставить дескриптор для отправки метода во время выполнения. В языке программирования Java используется правило, согласно которому выбирается наиболее конкретный c метод .

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

Все, что может быть передано методу String, также может быть передано методу Object в то время как есть вещи, которые вы можете передать методу Object, которые нельзя передать методу String (например, new Object()) (*); поэтому метод String более специфичен c, так что это тот, который выбран.


(*) Это предложение важно: если вы заменили метод Object, скажем, :

private static void doSomething(Integer s) {

тогда будут вещи, которые вы можете передать doSomething(String), которые вы не сможете передать doSomething(Integer); и были бы вещи, которые вы могли бы передать doSomething(Integer), которые вы не могли бы передать doSomething(String). В этом случае ни один из них не является более конкретным c, поэтому вызов метода будет считаться неоднозначным.

1 голос
/ 21 января 2020

В Java всегда выбирается более конкретная c версия метода, чем общая c. Если переданный параметр имеет тип String, он всегда будет использовать метод с параметром String, а не generi c object one.

0 голосов
/ 21 января 2020

Java следует подходу раннего связывания, поэтому во время компиляции он выбирает наиболее конкретный c method.most специфицируемый c метод выбирается путем сопоставления количества параметров и типа параметра в случае перегрузки метода. Ваш случай разрешения метода вызова типа параметра используется для разрешения вызова метода, так как количество параметров в обоих методах одинаково.

...