5

My initial question was an exact duplicate of this one; that is, why is it that this interface has a runtime retention policy.

But the accepted answer does not satisfy me at all, for two reasons:

  • the fact that this interface is @Documented has (I believe) nothing to do with it (although why @Documented has a runtime retention policy is a mystery to me as well);
  • even though many "would be" functional interfaces existed in Java prior to Java 8 (Comparable as the answer mentions, but also Runnable etc), this does not prevent them from being used as "substitutes" (for instance, you can perfecty well use a DirectoryStream.Filter as a substitute to a Predicate if all you do is filter on Path, for instance).

But still, it has this retention. Which means that it has to influence the JVM behavior somehow. How?

Community
  • 1
  • 1
fge
  • 119,121
  • 33
  • 254
  • 329
  • 1
    That is a very strange conclusion that having the retention policy `RUNTIME` implies that it has an influence on the JVM behavior. Since you already know that you can implement functional interfaces with lambda expressions, even when they don’t have that annotation (I suppose that you know that), what kind of change in JVM behavor should something entirely optional have? – Holger Feb 19 '16 at 10:20
  • @Holger that is precisely what I wondered, hence the question. But ultimately, it seems that it makes no difference... – fge Feb 19 '16 at 10:27

2 Answers2

5

I've found the thread in core-libs-dev mailing list which discusses the retention of @FunctionalInterface annotation. The main point mentioned here is to allow third-party tools to use this information for code analysis/validation and to allow non-Java JVM languages to map correctly their lambdas to functional interfaces. Some excerpts:

Joe Darcy (original committer of @FunctionalInterface):

We intentionally made this annotation have runtime retention to allow it to also be queried to various tools at runtime, etc.

Brian Goetz

There is a benefit for languages other than Java, that can use this as a means to determine whether the interface is suitable for passing to the SAM conversion machinery. The JDK support for lambda conversion is available to other languages as well.

So seems that it's not used by JVM itself, it's just an additional possibility for third-party tools. Making the annotation runtime-visible is not a big cost, so seems there were no strong reasons not to do this.

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • 1
    Actually, making an annotation runtime-visible *reduces* the costs. The byte code representation is identical, only the attribute name changes from `RuntimeInvisibleAnnotations` to `RuntimeVisibleAnnotations`, so you’re going to save at least two bytes per class file. Given that you may have other runtime-visible annotations while invisible annotations are very uncommon, the saving might be even higher as it might avoid having both attribute names present in a class file. – Holger Feb 19 '16 at 10:27
  • 1
    @Holger, while it may decrease class-file size a little, it increases the runtime cost as runtime visible annotations become java objects when you request `Class.getAnnotations()`. Seems that if you request it, the information about `@FunctionalInterface` will stuck in memory until the class is unloaded, even if you actually looked for some other annotation. Still this is not very big cost given the fact that only a small fraction of loaded classes is annotated with `@FunctionalInterface`. – Tagir Valeev Feb 19 '16 at 10:54
1

The only requirement for annotations with retention policy runtime is

Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively. (https://docs.oracle.com/javase/7/docs/api/java/lang/annotation/RetentionPolicy.html#RUNTIME)

Now this has some consequences on runtime behaviour, since the class loader must load these annoations and the VM must keep these annotations in memory for reflective access (for example by third party libraries).

There is however no requirement for the VM to act on such annotations.

Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34