Рассмотрим следующий пример:аннотаций для поддержки рефакторинга функционального интерфейса
public interface Greeter {
String greet();
}
public class ExplicitGreeterImpl implements Greeter {
@Override
public String greet() {
return "Hello World!";
}
}
public class ImplicitGreeterImpl {
public String doTheGreeting() {
return "Hello World!";
}
}
private void run() {
System.out.println(new ExplicitGreeterImpl().greet());
Greeter foo = new ImplicitGreeterImpl()::doTheGreeting;
System.out.println(foo.greet());
}
Функциональный интерфейс Greeter
имеет две реализации. ExplicitGreeterImpl
применяет Greeter
, используя пункт implements
, а ImplicitGreeterImpl::doTheGreeting
осуществляет Greeter
без него. Тем не менее, ImplicitGreeterImpl::doTheGreeting
предназначен для реализации Greeter
, как и ExplicitGreeterImpl
.
Теперь я хочу, чтобы реорганизовать интерфейс Greeter
, так что я могу передать имя ему:
public interface Greeter {
String greet(String name);
}
я могу сделать это с Signature рефакторинга Изменить метод, предоставляемого Затмение (я уверен, что другого IDE имеют аналогичный рефакторинг). Это автоматически обновляет все реализации и способы использования интерфейса Greeter
. Реализации получают новый параметр, в то время как обычаи передают настраиваемое значение по умолчанию. Это отлично подходит для ExplicitGreeterImpl
, однако рефакторинг не касается метода ImplicitGreeterImpl::doTheGreeting
. Таким образом, назначение
Greeter foo = new ImplicitGreeterImpl()::doTheGreeting;
будет ошибкой времени компиляции. Чтобы исправить это, мне нужно вручную настроить подпись метода ImplicitGreeterImpl::doTheGreeting
.
Теперь я понимаю, что во многих случаях нежелательно автоматически настраивать подпись ImplicitGreeterImpl::doTheGreeting
. Тем не менее, я чувствую, что текущий рабочий процесс может быть улучшен:
- Eclipse не отображает предупреждение в предварительном просмотре рефакторинга, из которого следует, что будет ошибка времени компиляции.
- Должна быть предусмотрена возможность аннотировать метод, чтобы уточнить, что предполагается реализовать данный функциональный интерфейс.
Например, ImplicitGreeterImpl
может выглядеть следующим образом:
public class ImplicitGreeterImpl {
@Implements(Greeter.class)
public String doTheGreeting() {
return "Hello World!";
}
}
Теперь инструменты рефакторинга может быть уверен, что ImplicitGreeterImpl::doTheGreeting
предполагается реализовать Greeter
и, таким образом, они могут автоматически изменить свою подпись.
Таким образом, мой вопрос: есть ли способ показать инструменты рефакторинга, что данный метод должен реализовывать данный функциональный интерфейс? Я искал предложенную выше аннотацию, но я не нашел ничего полезного.
Там действительно хороший причина не реализовывать интерфейс напрямую, а использовать ссылку на метод. Рассмотрим шаблон команды. В этом случае: (1) Интерфейс Command, вероятно, является функциональным интерфейсом, (2) существует множество реализаций интерфейса Command и (3) каждая из этих реализаций очень проста. Добавление дополнительного класса для каждой из этих реализаций добавляет много шума в код. Однако, если каждая реализация Command является всего лишь методом, код становится намного чище. –