4

I understand that a bunch of methods with body are added using default keyword of Java 8. My question is where is this annotation useful? I see that only one abstract method is allowed to be added with such annotation. But Comparator has two abstract methods :

  • int compare(T o1, T o2);
  • boolean equals(Object obj);

Also , Please explain the use of this annotation? I see that its a runtime annotation, so what are its uses ?

javaAndBeyond
  • 520
  • 1
  • 9
  • 26
  • 2
    This has your answer I think: http://stackoverflow.com/questions/28166187/why-it-isnt-functionalinterface-used-on-all-the-interfaces-in-the-jdk-that-qua – Tunaki Jan 17 '16 at 18:49
  • What makes you think that `equals` is abstract? – Pshemo Jan 17 '16 at 18:58
  • I meant two methods. Edited....thanks – javaAndBeyond Jan 17 '16 at 18:58
  • The source code I a looking at is an abstact method. Its not declared as a default method, in interface. So its abstract. – javaAndBeyond Jan 17 '16 at 19:00
  • `equals()` is not abstract. And just for you to know comparator also have `hashCode()` method, just like every other class – coolguy Jan 17 '16 at 19:02
  • 3
    @coolguy: The difference is that `Comparator` actually declares `equals`, but doesn't declare `hashCode`. So `equals` is part of the interface definition, listed in the JavaDoc, etc.; `hashCode` is not, although of course an *implementation* of `Comparator` would inherit from `Object` and get it. – T.J. Crowder Jan 17 '16 at 19:06
  • 1
    What is the point of declaring equals method ? They could have left it like hashcode method? – javaAndBeyond Jan 17 '16 at 19:08
  • 2
    @user2296988 One of probable reasons is to provide more specific documentation of that method in Comparator's context. It may be similar to "why ArrayList implements List when it already extends AbstractList?". – Pshemo Jan 17 '16 at 19:10
  • 1
    Related: [Why does Comparator declare equals?](http://stackoverflow.com/questions/11013850/why-does-comparator-declare-equals) – Pshemo Jan 17 '16 at 19:13
  • I get it. Its declared just to indicate the implementation class to override the equals method. It _may_ improve performance. But hashcode need not be overridden. And functional interface does not care about these. – javaAndBeyond Jan 17 '16 at 19:14
  • 1
    Also see: http://stackoverflow.com/questions/25222575/should-comparablet-be-a-functional-interface – Brian Goetz Jan 17 '16 at 21:21

2 Answers2

6

From the documentation of FunctionalInterface :

If an interface declares an abstract method overriding one of the public methods of java.lang.Object, that also does not count toward the interface's abstract method count since any implementation of the interface will have an implementation from java.lang.Object or elsewhere.

Since equals is from java.lang.Object, it's not counted. It's the compare method that relates to FunctionInterface.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Mrinal
  • 1,846
  • 14
  • 17
  • Thanks. Can you please explain the use of this annotation? I see that its a runtime annotation, so what are its uses other than using it with instanceof operator? – javaAndBeyond Jan 17 '16 at 21:06
  • 1
    @user2296988 it's primarily there for documentation and static analysis tools, e.g. to suggest where IDEs ought to suggest changing anonymous classes to lambdas. – Louis Wasserman Jan 17 '16 at 21:22
  • 2
    More precisely, it's purpose is to _capture design intent_. The specific design intent here is that this interface describes a standalone behavior (compute a function, dispense a resource, etc), and therefore is sensible to use as a target type for lambdas and method refs. – Brian Goetz Jan 17 '16 at 21:36
  • “uses other than using it with instanceof operator” is a strange premise. It’s rather untypical to use the instanceof operator together with annotations. A typical use case would rather look like `Foo.class.hasAnnotation(FunctionalInterface.class)`… – Holger Jan 18 '16 at 10:04
2

It is useful since if you add it and you have more than one method in the interface you will get a compile error. @FunctionalInterfaces are used to let Java know that this piece of code might be replaced with a lambda expression since every lambda is an implementation of some @FunctionalInterface. It helps the compiler know what is the method signature.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Orr Levinger
  • 104
  • 3