Метод неоднозначен - Java

Я пытался использовать некоторые примеры и не мог понять причину следующей ошибки кода в следующем примере

public class Test {
public static void print(Integer object){
 System.out.println("object");
}
public static void print(String string){
 System.out.println("String");
}
public static void main(String... args){
 print(null);
}
}

Я получаю сообщение об ошибке: Метод print (Integer) неоднозначен для типа Test

но когда я пытаюсь использовать один и тот же пример, меняя Integer на Object, код компилируется отлично и дает результат как String

public class Test {
public static void print(Object object){
 System.out.println("object");
}
public static void print(String string){
 System.out.println("String");
}
public static void main(String... args){
 print(null);
}
}

Может кто-нибудь, пожалуйста, помогите мне понять, почему метод с объектом в его сигнатуре требуется, когда вывод - это метод, в котором есть String. И в чем причина неоднозначной ошибки типа.

3 ответа

Integer и String не находятся в одинаковых иерархиях. Это означает, что вы не можете назначить String в Integer и наоборот.

но это не случай с String и Object потому что в java каждый класс по умолчанию расширяет класс Object.

Спецификация языка Java (JLS) в разделе 15.12. Вычисления вызова метода подробно объясняют процесс, который следующий компилятор выбирает, чтобы выбрать правильный метод для вызова.

Там вы заметите, что это задача времени компиляции. JLS говорит в подразделе 15.12.2:

На этом этапе используется имя метода и типы выражений аргументов для поиска доступных и применимых методов. Может быть более одного такого метода, и в этом случае выбирается наиболее конкретный.

Узнайте больше о правилах перегрузки Java

См. Перегрузка метода и выбор наиболее конкретного типа

Посмотрите ниже пример кода, где Integer и Number находятся в той же иерархии, почему он действителен.

class Test {
 public void print(Integer object) {
 System.out.println("object");
 }

 public void print(Number string) {
 System.out.println("String");
 }
}
new Test().print(null);


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

public class Test {
public static void printInteger(Integer object){
 System.out.println("object");
}
public static void printString(String string){
 System.out.println("String");
}
public static void main(String... args){
 printInteger(null);
}
}


Null не имеет типа в Java. Когда вы вызываете print(null), компилятор не знает, хотите ли вы вызвать функцию print(String) или функцию print (Integer).

Решение состоит в том, чтобы явно ввести в тип, который вы хотите назвать

print((Integer)null);

или

print((String)null);

licensed under cc by-sa 3.0 with attribution.