9

Is below interface a valid functional interface in Java 8?

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

Why doesn't it give me a compile time error?

Naman
  • 27,789
  • 26
  • 218
  • 353
Nitin T
  • 140
  • 1
  • 10
  • Why doesnt it give me compile time error – Nitin T Feb 23 '20 at 06:53
  • Could you please share your logs of the platform on which you're running your code? – Alok Feb 23 '20 at 07:14
  • 2
    Interesting question. I don't understand the close votes. But Nitin, please learn how to write good questions. Don't just post code, also put the actual question into your text, not into the headline or into a comment only. And edit questions rather than commenting if you want to add something to the question. I will do that for you this time. Please also be advised to learn how to use code blocks, I also fixed your code formatting. – kriegaex Feb 23 '20 at 07:21
  • In short: **Transitive declaration of methods.** – Vishwa Ratna Feb 24 '20 at 07:07

1 Answers1

11

What Alok quoted is true, but he overlooked something, which makes his final answer (that the code is invalid) wrong:

The interface has one method String toString() which every class already implements, inheriting it from Object. I.e. the declared interface method already has an implementation, similar to a default method. Hence, there is no compile error and Normal can be used as a functional interface as shown in my MCVE:

package de.scrum_master.stackoverflow;

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

BTW, no need to declare interface methods as public because they always are. Same goes for 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");
  }
}

If you run the driver application, you will see this console log:

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

Now if you change the method name toString to something else, e.g. toStringX, you will see that due to the @FunctionalInterface there is the expected error message when compiling the class:

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
  • 63,017
  • 15
  • 111
  • 202