15

Said in Javadoc:

If a type is annotated with this annotation type, compilers are required to generate an error message unless ...

Why isn't SOURCE or CLASS enough, like for @Override.

Sean Patrick Floyd
  • 284,665
  • 62
  • 456
  • 576
auntyellow
  • 2,229
  • 2
  • 16
  • 39

3 Answers3

6

The @FunctionalInterface annotation serves two purposes. Regarding the compiler and the error it has to generate it would be indeed enough to have a SOURCE RetentionPolicy as in this regard it only affects the very class annotated with @FunctionalInterface.

However, it has a second purpose, documenting the fact that using this interface as a functional interface is indeed intended and the possibility to use it this way not just a coincidence like with, e.g. Comparable which is not intended to be used that way.

Therefore it is annotated with @Documented and has the maximum RetentionPolicy to fulfill the second purpose.

Holger
  • 267,107
  • 35
  • 402
  • 715
  • Does each @Documented interface have the maximum RetentionPolicy (RUNTIME)? – auntyellow Nov 25 '14 at 10:45
  • 2
    @auntyellow: It’s not a hard requirement, however, it’s purpose of making the information broadly available leads to the conclusion that you usually *want* maximum retention. By the way `RetentionPolicy.CLASS` does not offer any advantage over `RUNTIME`. It consumes the same amount of space within a class file and since Reflection loads annotations only on demand, there is no benefit in not being available within the runtime either. – Holger Nov 25 '14 at 11:18
2

"Source" would not be enough, since if for example you create an API and provide your class as a pre-compiled jar, the information would not be available for the compiler anymore.

I believe "class" would also not be enough if you want to support those kind of compilers that "compile" against a class at runtime, like scripting engines that use reflection to find out about those annotations and should show a warning, too.

Sebastian
  • 7,258
  • 2
  • 36
  • 67
1

@FunctionalInterface is for runtime reflection, compile check, and java runtime process probably.

javap is used to de-compile and compare two interfaces, one with @FunctionalInterface, the other none.

Just extra two lines byte code in @FunctionalInterface tagged interface:

Constant pool:
   #7 = ...   RuntimeVisibleAnnotations
   #8 = ...   Ljava/lang/FunctionalInterface;

And both implementation/lambda express are same at byte code level.

Except for interface reflection:

X.class.getAnnotation(FunctionalInterface.class) == null?;
卢声远 Shengyuan Lu
  • 30,386
  • 22
  • 82
  • 125