Выбор перегруженного метода на основе реального типа параметра

клиентские рычаги мерзавца не выполняются на сервере - но почему нет?

Обычно Вы продвигаете к пустому repo (repo без рабочего дерева, где Вы не можете делать любую фиксацию непосредственно)
Так , фиксации серверной стороны больше об осуществлении политик, чем создание новых фиксаций.

при реальной необходимости в новом содержании, которое будет создано на стороне сервера (особенно один у Вас нет прямого управления, как GitLab.com), Вам было бы нужно:

  • любой для активации некоторого рычага серверной стороны, который на данный момент только доступен в GitHub, с действия GitHub .
  • или установка слушатель GitLab webhook: это, которое webhook позвонил бы (на каждое нажатие события ) Вашему слушателю, который мог в свою очередь получить последнюю историю, сделать любую модификацию, Вы нуждаетесь, создаете новую фиксацию и пододвигаете обратно.
107
задан Sergey Mikhanov 15 October 2009 в 13:19
поделиться

5 ответов

Я ожидаю, что выбор метода примет принимая во внимание реальную (а не объявлен) тип параметра. Я скучаю что-нибудь?

Да. Ваше ожидание неверно. В Java отправка динамических методов происходит только для объекта, для которого вызывается метод, а не для типов параметров перегруженных методов.

Ссылаясь на Спецификацию языка Java :

Когда метод вызывается ( §15.12), количество фактических аргументов (и любые явные аргументы типа) и типы аргументов во время компиляции используются во время компиляции для определить сигнатуру метода который будет вызван (§15.12.2). Если вызываемый метод - это метод экземпляра, фактический метод для быть вызванным, будет определено при запуске время, используя поиск динамического метода (§15.12.4).

91
ответ дан 24 November 2019 в 03:40
поделиться

Возможность отправки вызова метода на основе типов аргументов называется множественной отправкой . В Java это делается с помощью шаблона Visitor .

Однако, поскольку вы имеете дело с Integer s и String s, вы не можете легко включить этот шаблон (вы просто не можете изменять эти классы). Таким образом, вы предпочитаете гигантский переключатель во время работы объекта.

15
ответ дан 24 November 2019 в 03:40
поделиться

Как упоминалось ранее, разрешение перегрузки выполняется во время компиляции.

Java Puzzlers имеет хороший пример для этого:

Головоломка 46: Случай сбивающего с толку конструктора

] Эта головоломка представляет вам два сбивающих с толку конструктора. Основной метод вызывает конструктор, но какой? Результат работы программы зависит от ответа. Что печатает программа, или это даже законно?

public class Confusing {

    private Confusing(Object o) {
        System.out.println("Object");
    }

    private Confusing(double[] dArray) {
        System.out.println("double array");
    }

    public static void main(String[] args) {
        new Confusing(null);
    }
}

Решение 46: Случай сбивающего с толку конструктора

... Процесс разрешения перегрузки Java работает в два этапа. На первом этапе выбираются все доступные и применимые методы или конструкторы. На втором этапе выбираются наиболее конкретные из методов или конструкторов, выбранных на первом этапе. Один метод или конструктор менее специфичен , чем другой, если он может принимать любые параметры, переданные другому [JLS 15.12.2.5].

В нашей программе оба конструктора доступны и применимы. Конструктор Confusing (Object) принимает любой параметр, переданный в Confusing (double []) , поэтому Смущающий (Объект) менее конкретен. (Каждый двойной массив является объектом , но не каждый объект является двойным массивом ).) Таким образом, наиболее точным конструктором является ] Запутывает (double []) , объясняющее вывод программы.

Такое поведение имеет смысл, если вы передаете значение типа double [] ; это нелогично, если вы передадите null . Ключ к пониманию этой загадки заключается в том, что тест, для которого метод или конструктор наиболее специфичен, не использует фактические параметры : параметры, появляющиеся в вызове. Они используются только для определения возможных перегрузок. Как только компилятор определяет, какие перегрузки применимы и доступны, он выбирает наиболее конкретную перегрузку, используя только формальные параметры: параметры, указанные в объявлении.

Чтобы вызвать конструктор Confusing (Object) с помощью нулевой параметр, запись новый Непонятно ((Object) null) . Это гарантирует, что применимо только Confusing (Object) . Больше обычно, чтобы заставить компилятор выбрать конкретную перегрузку, приведите фактические параметры к объявленным типам формальных параметров.

83
ответ дан 24 November 2019 в 03:40
поделиться

Java смотрит на ссылочный тип при попытке определить, какой метод вызвать. Если вы хотите заставить свой код выбрать «правильный» метод, вы можете объявить свои поля как экземпляры определенного типа:

Integeri = new Integer(12);
String s = "foobar";
Object o = new Object();

Вы также можете указать свои параметры как тип параметра:

callee.foo(i);
callee.foo((String)s);
callee.foo(((Integer)o);
2
ответ дан 24 November 2019 в 03:40
поделиться

В Java метод для вызова (как и в какой сигнатуре метода использовать) определяется во время компиляции, поэтому он соответствует типу времени компиляции.

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

    public void foo(Object o) {
        if (o instanceof String) foo((String) o);
        if (o instanceof Integer) foo((Integer) o);
        logger.debug("foo(Object o)");
    }

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

11
ответ дан 24 November 2019 в 03:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: