JavaRush /Курсы /Java Core /Перегрузка методов | часть 2

Перегрузка методов | часть 2

Java Core
5 уровень , 3 лекция
Открыта

— Привет, Амиго! Пару дней назад я тебе рассказывал о перегрузке методов. Ты все понял?

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

— Отлично! Я вижу, что ты хорошо выучил тот урок. Сегодня я хочу лишь немного расширить твои познания в этом деле. Как ты думаешь, какой метод будет вызван в каждом случае?

Код
class Cat {
    public static void print(int n) {
        System.out.println(n);
    }
    public static void print(short n) {
        System.out.println(n);
    }
    public static void print(Integer n) {
        System.out.println(n);
    }
    public static void print(String s) {
        System.out.println(s);
    }
    public static void main(String[] args) {
        Cat.print(1);
        Cat.print((byte)1);
        Cat.print("1");
        Cat.print(null);
    }
}

— Затрудняюсь ответить.

— В первом случае 1 имеет тип int, у нас есть 100% совпадение метода, который принимает int. Будет вызван первый void print(int n).

Во втором случае, у нас нет метода, который принимает byte. Но есть два метода, которые принимают short и int. По стандарту расширения типов, byte сначала будет расширен до short, а уж затем расширен до int. Вердикт – будет вызван метод void print(short n).

В третьем случае у нас есть 100% совпадение метода, который принимает String. Будет вызван метод void print(String s).

В четвертом случае у нас неопределенность. null не имеет определенного типа, компилятор откажется компилировать этот код. В таком случае нужно написать Cat.print((Integer)null), чтобы вызвать третий метод и Cat.print((String)null), чтобы вызвать четвертый.

— Очень познавательно, спасибо.

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

Код
class Cat {
    public static void print(short n) {
        System.out.println(n);
    }
    public static void print(Integer n) {
        System.out.println(n);
    }

    public static void main(String[] args) {
        Cat.print((byte)1);
        Cat.print(1);
    }
}

В первом случает, тип byte будет расширен до short и произойдет вызов первого метода: void print(short n).

Во втором случае неявно будет выполнено разрешенное преобразование от int к Integer, и произойдет вызов второго метода void print(Integer n).

— Неожиданно.

— Нет, неожиданно – это тут:

Код на Java Описание
 class Cat {
    public static void print(Object o) {
        System.out.println(o);
    }
    public static void print(String s) {
        System.out.println(s);
    }

    public static void main(String[] args) {
        Cat.print(1);
        Cat.print(null);
    }
}
В первом случае int будет расширен до Integer, а так как нет метода для Integer, то вызовется наиболее подходящий метод, т.е. метод void print(Object o)

Во втором случае, ошибки компиляции не будет и вызовется метод void print(String s), что несколько не очевидно.

— Надеюсь, Амиго ты понял, что лучше всего в таких случаях указать оператор преобразования типа, как в случае с (byte), чтобы точно знать, какой метод вызовется.

— Уж от чего, от чего, а от перегрузки методов я никаких проблем не ожидал. И тут – на тебе. Спасибо, Риша, буду держать ухо востро и не расслабляться.

Комментарии (292)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Anonymous #3585174 Уровень 33
18 августа 2025
Like
Seka Уровень 16
6 августа 2025
поставьте лайк на этот коммент и вы получите ответ на возникший у вас вопрос касательно null в первом и во втором случае. просто нажмите на "популярные" комментарии. Нужна ачивка)
Trofim Veselov Уровень 30
13 июня 2025
Не копипаста для тех, кто печатает копипасту, чтоб его сообщение было популярным: Для тех кто копирует нижний комментарий по вопросу про String и null, и пока копипаста не опуститься - она собирает собирает лайки, потому что есть те, кому лень нажать на самые популярные и эти самые "те" читают только первые несколько комментариев, а вопрос про String и null появился: Похоже, Ваш план по сбору ачивки работает!
Victor Уровень 36
28 марта 2025
Похоже Риша не раскрыл тему, зато комментарии раскрыли тему полностью.
Pyramid Head First Уровень 32
22 марта 2025
Копипаста для тех кому лень нажать на самые популярные: Для тех кто читает только первые несколько комментариев, а вопрос про String и null появился: "В первом примере он не может скомпилироваться не от того, что null не может взять не один конструктор, а наоборот, его готовы взять сразу два: String и Integer. Поэтому возникает неопределенность на которую указывает компилятор. Во втором примере, null тоже готовы взять двое, но так как String - потомок Object'a, предпочтение отдается String'у. Не будь его, null взял бы себе Object."
kddima0 Уровень 25
8 марта 2025
Не понял, мы ведь тут делаем даункастинг, а не апкастинг: мы short сужаем до byte, а не наоборот. Почему я не прав, не понимаю. Посните пожалуйста "Во втором случае, у нас нет метода, который принимает byte. Но есть два метода, которые принимают short и int. По стандарту расширения типов, byte сначала будет расширен до short, а уж затем расширен до int". Мы ведь тут приводим short к byte: Cat.print((byte)1);
lom1tr Уровень 44
12 декабря 2024
Копипаста для тех кому лень нажать на самые популярные: Для тех кто читает только первые несколько комментариев, а вопрос про String и null появился: "В первом примере он не может скомпилироваться не от того, что null не может взять не один конструктор, а наоборот, его готовы взять сразу два: String и Integer. Поэтому возникает неопределенность на которую указывает компилятор. Во втором примере, null тоже готовы взять двое, но так как String - потомок Object'a, предпочтение отдается String'у. Не будь его, null взял бы себе Object."
12 декабря 2024
Не буду писать "Копипаста ..." Просто советую прочитать комментарий ниже👇
Evil Rokk17 Уровень 27
3 декабря 2024
Копипаста для тех кому лень нажать на самые популярные: Для тех кто читает только первые несколько комментариев, а вопрос про String и null появился: "В первом примере он не может скомпилироваться не от того, что null не может взять не один конструктор, а наоборот, его готовы взять сразу два: String и Integer. Поэтому возникает неопределенность на которую указывает компилятор. Во втором примере, null тоже готовы взять двое, но так как String - потомок Object'a, предпочтение отдается String'у. Не будь его, null взял бы себе Object."
Santa (RU) Уровень 29
3 декабря 2024
Копипаста для тех кому лень нажать на самые популярные: Для тех кто читает только первые несколько комментариев, а вопрос про String и null появился: "В первом примере он не может скомпилироваться не от того, что null не может взять не один конструктор, а наоборот, его готовы взять сразу два: String и Integer. Поэтому возникает неопределенность на которую указывает компилятор. Во втором примере, null тоже готовы взять двое, но так как String - потомок Object'a, предпочтение отдается String'у. Не будь его, null взял бы себе Object."