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


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

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 методами?

7 109

7 ответов:

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 точно знает, какой метод вызывать, так как он будет учитывать тип переменной.

каждая пара этих трех методов неоднозначна сама по себе при вызове с

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

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

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

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

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

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

class Sample{
  public static void main (String[] args) {
       Sample s = new Sample();
       s.printVal(null);

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

    public static void printVal(Integer i){
        System.out.println("Int called "+i);
    }
}

выход Int называется null и поэтому неоднозначность с char[] и Integer