Почему нет ошибки компиляции для моего @FunctionalInterface с двумя методами? - PullRequest
8 голосов
/ 23 февраля 2020

Является ли приведенный ниже интерфейс допустимым функциональным интерфейсом в Java 8?

@FunctionalInterface
interface Normal{
    public abstract String move();
    public abstract String toString() ;
}

Почему он не выдает ошибку времени компиляции?

Ответы [ 2 ]

10 голосов
/ 23 февраля 2020

То, что Alok процитировано, верно, но он что-то упустил, что делает его окончательный ответ (что код неверен) неверным:

Интерфейс имеет один метод String toString(), который каждый класс уже реализует, наследуя его от Object. Т.е. заявленный интерфейсный метод уже имеет реализацию, аналогичную методу по умолчанию. Следовательно, нет ошибки компиляции, и Normal может использоваться как функциональный интерфейс, как показано в моем MCVE :

package de.scrum_master.stackoverflow;

@FunctionalInterface
interface Normal {
  String move();
  String toString();
}

Кстати, нет необходимости объявлять методы интерфейса как public потому что они всегда есть. То же самое касается abstract.

package de.scrum_master.stackoverflow;

public class NormalApp {
  static void doSomething(Normal normal) {
    System.out.println(normal.move());
    System.out.println(normal.toString());
  }

  public static void main(String[] args) {
    doSomething(() -> "xxx");
  }
}

Если вы запустите приложение драйвера, вы увидите этот журнал консоли:

xxx
de.scrum_master.stackoverflow.NormalApp$$Lambda$1/1530388690@28c97a5

Теперь, если вы измените имя метода toString на что-то еще, например toStringX, вы увидите, что из-за @FunctionalInterface появляется ожидаемое сообщение об ошибке при компиляции класса:

Unexpected @FunctionalInterface annotation
  de.scrum_master.stackoverflow.Normal is not a functional interface
    multiple non-overriding abstract methods found in interface de.scrum_master.stackoverflow.Normal
0 голосов
/ 23 февраля 2020

Прежде всего, Нитин, вам нужно провести надлежащее исследование этого вопроса, а затем вы должны прийти на эту платформу, чтобы спросить о вашей проблеме.

Тем не менее, прежде всего, позвольте мне прояснить ваши сомнения по поводу Функциональный интерфейс в Java 8

  1. Функциональный интерфейс в Java 8 может иметь только один абстрактный метод и любое количество методов по умолчанию.
  2. Начиная с Java 8 и далее лямбда-выражения могут использоваться для представления экземпляра функционала interface.
  3. @ Аннотация FunctionalInterface используется, чтобы гарантировать, что функциональный интерфейс не может иметь более одного абстрактного метода. Если присутствует более одного абстрактного метода, компилятор помечает сообщение Unexpected @FunctionalInterface annotation. Однако использовать эту аннотацию не обязательно.

Согласно только вашему коду, я мог видеть два абстрактных метода, , следовательно, ваш код неверен .

Надеюсь, это поможет вам в некотором роде. Для получения дополнительной информации перейдите по этой ссылке: Java 8 Функциональный интерфейс

...