¿Por qué no hay un error de compilación para mi @FunctionalInterface con dos métodos?

8

¿La siguiente interfaz es una interfaz funcional válida en Java 8?

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

¿Por qué no me da un error de tiempo de compilación?

Nitin T
fuente
¿Por qué no me da un error de tiempo de compilación
Nitin T
¿Podría compartir sus registros de la plataforma en la que está ejecutando su código?
Alok
1
Interesante pregunta. No entiendo los votos cerrados. Pero Nitin, por favor aprende a escribir buenas preguntas. No solo publique el código, también ponga la pregunta real en su texto, no en el título o solo en un comentario. Y edite preguntas en lugar de comentar si desea agregar algo a la pregunta. Lo haré por ti esta vez. Tenga en cuenta que también debe aprender a usar bloques de código, también arreglé el formato de su código.
kriegaex
En resumen: declaración transitiva de métodos.
Vishwa Ratna

Respuestas:

10

Lo que Alok citó es cierto, pero pasó por alto algo, lo que hace que su respuesta final (que el código no es válido) sea incorrecta:

La interfaz tiene un método String toString()que cada clase ya implementa, heredando Object. Es decir, el método de interfaz declarado ya tiene una implementación, similar a un método predeterminado. Por lo tanto, no hay un error de compilación y Normalpuede usarse como una interfaz funcional como se muestra en mi MCVE :

package de.scrum_master.stackoverflow;

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

Por cierto, no es necesario declarar los métodos de interfaz publicporque siempre lo son. Lo mismo 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");
  }
}

Si ejecuta la aplicación del controlador, verá este registro de consola:

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

Ahora, si cambia el nombre del método toStringa otro, por ejemplo toStringX, verá que debido al @FunctionalInterfacemensaje de error esperado al compilar la clase:

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
fuente
Gran respuesta Kriegaex.
Alok
1
Gran explicación, +1
Sandeep Tiwari
-1

En primer lugar, Nitin, debe tener una investigación adecuada sobre esto, y luego debe venir a esta plataforma para preguntar sobre su problema.

Sin embargo, antes que nada, permítame aclarar su duda sobre la interfaz funcional en Java 8

  1. La interfaz funcional en Java 8 solo puede tener un método abstracto y cualquier número de métodos predeterminados.
  2. Desde Java 8 en adelante, las expresiones lambda se pueden usar para representar la instancia de una interfaz funcional.
  3. La anotación @FunctionalInterface se utiliza para garantizar que la interfaz funcional no pueda tener más de un método abstracto. En caso de que haya más de un método abstracto, el compilador marca un Unexpected @FunctionalInterface annotationmensaje. Sin embargo, no es obligatorio usar esta anotación.

Según su código solamente, pude ver dos métodos abstractos, por lo tanto , su código no es válido .

Espero que te ayude de alguna manera. Para obtener más información, consulte este enlace: Interfaz funcional Java 8

Alok
fuente
1
aunque no entendiste mi pregunta si @FunctionalInterface le asegura al compilador que mi interfaz debería tener solo un método abstracto, entonces por qué el código anterior no me da un error de tiempo de compilación, solo necesito una respuesta para eso
Nitin T
@NitinT, vea en su declaración del problema lo que ha escrito válido o no . He dado una respuesta basada en esto. Investigue un poco sobre cómo hacer preguntas en StackOverFlow.
Alok