Por que não há erro de compilação para o meu @FunctionalInterface com dois métodos?

8

A interface abaixo é uma interface funcional válida no Java 8?

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

Por que isso não me dá um erro de tempo de compilação?

Nitina T
fonte
Por que não me dá erro de tempo de compilação
Nitin T
Você poderia compartilhar seus logs da plataforma na qual está executando seu código?
Alok 23/02
1
Pergunta interessante. Eu não entendo os votos próximos. Mas Nitin, por favor, aprenda a escrever boas perguntas. Não basta postar o código, também colocar a pergunta real no seu texto, não no título ou apenas em um comentário. E edite as perguntas em vez de comentar se você deseja adicionar algo à pergunta. Eu farei isso por você neste momento. Esteja ciente de que também deve aprender a usar blocos de código. Também corrigi sua formatação de código.
kriegaex 23/02
Em resumo: declaração transitiva de métodos.
Vishwa Ratna

Respostas:

10

O que Alok citou é verdade, mas ele ignorou algo, o que torna sua resposta final (que o código é inválido) errada:

A interface possui um método String toString()que toda classe já implementa, herdando-a Object. Ou seja, o método da interface declarada já possui uma implementação, semelhante a um método padrão. Portanto, não há erro de compilação e Normalpode ser usado como uma interface funcional, como mostrado no meu MCVE :

package de.scrum_master.stackoverflow;

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

BTW, não há necessidade de declarar métodos de interface como publicsempre. O mesmo vale para 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");
  }
}

Se você executar o aplicativo de driver, verá este log do console:

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

Agora, se você alterar o nome do método toStringpara outra coisa, por exemplo toStringX, verá que devido à @FunctionalInterfacemensagem de erro esperada ao compilar a classe:

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
kriegaex
fonte
Ótima resposta Kriegaex.
Alok 23/02
1
Ótima explicação, +1
Sandeep Tiwari 23/02
-1

Primeiro de tudo, Nitin, você precisa ter uma pesquisa adequada sobre isso e, em seguida, você deve entrar nesta plataforma para perguntar sobre o seu problema.

No entanto, antes de tudo, deixe-me esclarecer sua dúvida sobre a Interface Funcional em Java 8

  1. A Interface Funcional no Java 8 pode ter apenas um método abstrato e qualquer número de métodos padrão.
  2. A partir do Java 8, expressões lambda podem ser usadas para representar a instância de uma interface funcional.
  3. A anotação @FunctionalInterface é usada para garantir que a interface funcional não possa ter mais de um método abstrato. Caso mais de um método abstrato esteja presente, o compilador sinaliza uma Unexpected @FunctionalInterface annotationmensagem. No entanto, não é obrigatório usar esta anotação.

Conforme apenas o seu código, eu pude ver dois métodos abstratos; portanto , seu código é inválido .

Espero que ajude você de alguma forma. Para obter mais informações, consulte este link: Java 8 Functional Interface

Alok
fonte
1
alok você não entendi minha pergunta se @FunctionalInterface garante o compilador que minha interface deve ter apenas um método abstrato então por código acima não está me dando erro tempo de compilação eu só preciso de uma resposta para isso
Nitin T
@NitinT, veja na declaração do seu problema o que você escreveu válido ou não . Eu dei uma resposta com base nisso. Faça uma pesquisa sobre a pergunta no StackOverFlow.
Alok 23/02