Перегрузка метода для нулевого аргумента - программирование
Подтвердить что ты не робот

Перегрузка метода для нулевого аргумента

Я добавил три метода с параметрами:

public static  void doSomething(Object obj) {
    System.out.println("Object called");
}

public static  void doSomething(char[] obj) {
    System.out.println("Array called");
}

public static  void doSomething(Integer obj) {
    System.out.println("Integer called");
}

Когда я звоню doSomething(null), компилятор выдает ошибку как неоднозначные методы. Это проблема, потому что методы Integer и char[] или методы Integer и Object?

4b9b3361

Ответ 1

Java всегда будет пытаться использовать наиболее подходящую версию доступного метода (см. JLS §15.12.2).

Object, char[] и Integer могут принимать значение null как допустимое значение. Поэтому все 3 версии применимы, поэтому Java придется найти наиболее конкретный.

Так как Object является супертипом char[], версия массива более специфична, чем Object -версия. Поэтому, если существуют только эти два метода, будет выбрана версия char[].

Если доступны версии char[] и Integer, то оба из них более специфичны, чем Object, но ни один не более конкретный, чем другой, поэтому Java не может решить который можно назвать. В этом случае вам придется явно указать, какой из них вы хотите вызвать, отвечая аргумент соответствующему типу.

Заметим, что на практике эта проблема встречается гораздо реже, чем можно было бы подумать. Причина этого заключается в том, что это происходит только тогда, когда вы явно вызываете метод с null или с переменной довольно неспецифического типа (например, Object).

Наоборот, следующий вызов будет абсолютно однозначным:

char[] x = null;
doSomething(x);

Хотя вы все еще передаете значение null, Java точно знает, какой метод вызывать, поскольку он будет учитывать тип переменной.

Ответ 2

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

Ниже перечислены три способа вызова одного конкретного метода с нулевым значением.

doSomething( (Object) null);
doSomething( (Integer) null);
doSomething( (char[]) null);

Могу ли я предложить устранить эту двусмысленность, если вы на самом деле планируете называть эти методы аргументами null. Такой дизайн предлагает ошибки в будущем.

Ответ 3

null является допустимым значением для любого из трех типов; поэтому компилятор не может решить, какую функцию использовать. Вместо этого используйте что-то вроде doSomething((Object)null) или doSomething((Integer)null).

Ответ 4

Каждый класс в Java расширяет класс Object. Еще один класс Integer также расширяет Object. Следовательно, Object и Integer рассматриваются как экземпляр объекта. Поэтому, когда вы передаете значение null в качестве параметра, а компилятор запутывается, какой метод объекта вызывается, например, с параметром Object или параметром Integer, поскольку оба они являются объектами, а их ссылка может быть нулевой. Но примитивы в java не расширяют Object.

Ответ 5

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

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

Ответ 6

существует двусмысленность из-за doSomething (char [] obj) и doSomething (Integer obj).

char [], и Integer оба являются одинаковыми для null, поэтому они неоднозначны.