NOTE: This document contains old language design notes and does not correspond to the current state of Kotlin. Please see http://kotlinlang.org/docs/reference/annotations.html for up-to-date documentation on this topic.
Goals:
Related issues:
In Java annotation elements (this is the term java uses for “fields”/“attributes”/“properties” of an annotation) are defined as methods in the corresponding @interface
, so there is no ordering rule that we can use when loading a fictitious primary constructor for a Java annotation.
Example:
Let‘s say there’s a Java annotation with two elements:
@interface Ann { int foo(); String bar(); }
When we use it in Kotlin, we can use positional arguments:
[Ann(10, "asd")] class Baz
Now, it's both source- and binary- compatible to reorder methods in a Java interface:
@interface Ann { String bar(); int foo(); }
But the code above will break.
Also, we now load all array arguments as varargs, which may break for the same reason.
Fictitious constructors for Java annotations could be built as follows:
value
, it is put first on the parameter listvalue
has an array type, it is marked vararg
and has the type of the elements of the arrayvalue
can not be used positionally, only named arguments are allowed for them (this requires adding a platform-specific check to frontend.java
)NOTE: when
value
parameter is markedvararg
and no arguments are passed, behavior will depend on presence of parameter's default value:
Thus, behavior of the same code can change after adding a default value to parameter and recompiling kotlin sources
NOTE: Scala still uses Array(...)
in annotations, no matter how ugly it is
Option 1: Use []
for array literal
@User( firstName = "John", names = ["Marie", "Spencer"], lastName = "Doe" ) class JohnDoe @Values([FOO, BAR]) // ugly, but it's the same in Java: @Ann({FOO, BAR}) class WithValues
Option 2: Use @(...)
@User( firstName = "John", names = @("Marie", "Spencer"), lastName = "Doe" ) class JohnDoe @Values(@(FOO, BAR)) // looks bad class WithValues