2016-04-20 3 views
0

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

Почему Java выбирает метод с параметром String as, как java определяет, какой перегруженный метод нужно вызвать?

class TestingClass { 
    public void test(String s) { 
     System.out.println("String"); 
    } 

    public void test(Object o) { 
     System.out.println("Object"); 
    } 

    public static void main(String[] args) { 
     TestingClass q = new TestingClass(); 
     q.test(null); 
    } 
} 
+0

Повторите это после меня. Переопределение происходит только в производных классах, и это тоже, только если параметры метода одинаковы. Тип возврата допускается ковариантным. – Madhusudhan

+0

Более подробный текст, объясняющий, что сказал Эран. [Ищите ответ Дениса] (http://stackoverflow.com/questions/1572322/overloaded-method-selection-based-on-the-parameters-real-type) –

ответ

2

В этом коде нет переопределения, только перегрузка метода. Когда компилятор должен выбрать, какой из двух методов test выполнить (поскольку null может быть передан обоим), он выбирает тот, у которого более конкретный тип аргумента - test(String s) - String более конкретный, чем Object, поскольку он является подклассом от Object.

Другой метод может быть вызван с помощью:

q.test((Object) null); 
+0

Как строка более конкретна, чем Object? –

+1

@ jk2praj Подкласс является более конкретным, чем его суперкласс. Так определяется термин «более конкретный» в JLS. – Eran

+1

Поскольку String является подклассом Object. Если, однако, классы не связаны иерархией наследования, тогда вы получите ошибку времени компиляции – Madhusudhan

0

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

public class Overload { 

    public static void main(String[] args) { 
     new Overload().test(null); 
    } 

    public void test(String s) { 
     System.out.println("String"); 
    } 

    public void test(Object o) { 
     System.out.println("Object"); 
    } 

    public void test(Integer s) { 
     System.out.println("Integer"); 
    } 

} 

закомментировать один из объекта или Integer, посмотрите на это самостоятельно. Ответ уже предоставлен другими.