Почему разрешение перегрузки метода должно выполняться во время компиляции в JAVA? - PullRequest
0 голосов
/ 28 октября 2018

Здесь простой блок кода:

public class CYoungMan extends YoungMan{
    @Override
    public String meet(Object obj) {
        return obj.getClass().getSimpleName();
    }
    @Override
    public String meet(String str) {
        return "String class";
    }
    public static void main(String[] args) throws Throwable {
        Object str = "katie";
        YoungMan ym = new CYoungMan();
        ym.meet(str);
    }
}

Для вызова метода ym.meet(str), как мы знаем,

  1. компилятор определяет символьную ссылку, объединенную классом YoungMan и метод String meet(Object obj);
  2. затем во время выполнения JVM находит блок метода по типу времени выполнения ym и его иерархии наследования.

У меня вопрос, почемуне принять (1) для реализации во время выполнения, и мы находим метод перегрузки по типу параметров времени выполнения?

Что меня больше беспокоит, так это почему разработчики Java решили это сделать (как я описал в (1) и(2)) и почему бы вместо этого не выбрать несколько отправлений во время выполнения (как мое предложение)?Есть ли официальное объяснение? 1018 *

Ответы [ 2 ]

0 голосов
/ 28 октября 2018

Короткая версия такова, что именно так Java-система решила это сделать (помимо всего прочего, она намного быстрее во время выполнения).Groovy (среди других языков JVM) может выполнять динамическую диспетчеризацию, и invokedynamic был добавлен в набор инструкций JVM в Java 7, чтобы сделать этот подход более эффективным.

0 голосов
/ 28 октября 2018

Хотя перегруженные методы имеют одно и то же имя в коде, метод с n перегрузками будет иметь n разных сигнатур методов.Эти методы могут принимать и возвращать различные параметры и возвращаемые значения.Компилятору необходимо знать, какую сигнатуру метода использовать, чтобы понять, допустим ли код его компиляции.

Рассмотрим следующий перегруженный метод:

class Translator {
    String translate(int i) { return String.valueOf(i); }
    int translate(String s) { return Integer.valueOf(s); }
}

Эти методы имеют одно и то же имя, но имеют очень разные подписи.Если вы выберете одно против другого, вы можете получить неверный исполняемый файл.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...