Подтвердить что ты не робот

Полиморфизм и перегрузка метода

У меня есть быстрый и напряженный вопрос:

У меня есть этот простой класс:

public class A
{
    public void m(Object o)
    {
      System.out.println("m with Object called");
    }

    public void m(Number n)
    {
       System.out.println("m with Number called");
    }
    public static void main(String[] args)
    {
       A a = new A();
       // why will m(Number) be called?
       a.m(null);
    }
}

UPDATE: на самом деле это метод с вызываемым номером. Извините за путаницу.

Если я вызываю a.m(null), он вызывает метод с параметром Number.

Мой вопрос: почему это? где в спецификации языка Java указано это?

4b9b3361

Ответ 1

Прежде всего, он на самом деле вызывает m(Number).

Это происходит потому, что оба метода применимы, но m(Number) - наиболее специфический метод, так как любой аргумент m(Number) может быть передан в m(Object), но не наоборот.

Если вы замените m(Object) на m(String) (или добавите другой метод, например m(Date)), компилятор сообщит о двусмысленности, так как невозможно определить конкретный метод.

См. раздел Выбор наиболее конкретного метода в спецификации Java.

Ответ 2

  • Это не полиморфизм или переопределение. Это метод перегрузки.
  • Я тестировал это и вызывается конкретный метод (а не m (Object)), и в соответствии со спецификацией всегда вызывается конкретный метод. Какая перегрузка будет выбрана для null в Java?

Ответ 3

другой связанный с вами вопрос:

public static void main(String[] args)
{
   A a = new A();
   Object n = new Integer(1);
   a.m(n); // which method will be called?
}

Ответ 4

Мои 2 цента. Метод с аргументом Number - это тот, который вызывается, потому что Number расширяет Object. У меня была аналогичная ситуация в прошлом, я переопределил метод и поместил компонент вместо JComponent (по ошибке). Мне потребовалась неделя, чтобы выяснить причину, почему мой метод никогда не назывался. Я понимаю, что если есть некоторые отношения наследования между перегруженными методами, JVM сначала совпадает с более глубоким в иерархии классов.

Ответ 5

Object - это тип по умолчанию в Java. Если вы реорганизовываете свой метод m(Object o) на m(String o), у вас будет ошибка времени компиляции, говорящая, что вызов m(null) неоднозначен, потому что Java не может определить, какой класс между String и Number по умолчанию равен null

Кроме этого, между m(Object o) и m(Number o) вызов m(null) вызывает m(Number o), потому что это наиболее специализированный метод. В противном случае вам нужно будет отличить null от Object (или ничего, кроме экземпляра Number).

a.m((String) null);

Ответ 6

Jaguar, Согласно Спецификациям Java, да, это объект. Таким образом, метод, выбранный для m.m(true) в основном, относится к типу параметра Object.

Boolean определяется в Java.lang.Boolean Число определено в Java.lang.Number

(Оба объекта расширения)

Coders Rhyme book: "Когда в vex, ссылайтесь на спецификации"