Philip Graf
09/12/2022, 9:18 AMpublic class Pet {
private List<String> names;
public @NonNull List<@NonNull String> getNames() {
return names;
}
// constructor, setter, etc. omitted
}
I tried to write the following data class:
data class Pet(val names: @get:NonNull List<@get:NonNull String>)
For each of the annotations I get two compile errors:
- This annotation is not applicable to target 'undefined target' and use site target '@get'
- This annotation is not applicable to target 'type usage' and use site target '@get'
The NonNull annotation is from the Java library microprofile-graphql-api
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Documented
public @interface NonNull {
}
I run into the same problem when I try to set the annotations on the field:
data class Pet(val names: @field:NonNull List<@field:NonNull String>)
Is there a way to get annotations on the type and generic type of a getter method or field?Sam
09/12/2022, 9:32 AMdata class Pet(@get:NonNull val names: List<@NonNull String>)
• The first annotation is for the property getter (AnnotationTarget.PROPERTY_GETTER
). It goes before the property declaration, but needs the get:
use-site target otherwise it would annotate the constructor parameter by default.
• The second annotation is for the String
type parameter use. (In Kotlin, AnnotationTarget.TYPE
, in Java, ElementType.TYPE_USE
). There’s no use-site target for this because it’s the only valid target for an annotation in that position.Sam
09/12/2022, 9:40 AMdata class Pet(val names: @NonNull List<@NonNull String>)
I’m a bit fuzzy on what the difference would be in the resulting Java code, to be honest. I’ve been spoiled by writing Kotlin for too long 😄Sam
09/12/2022, 9:42 AMget:
).Philip Graf
09/12/2022, 11:31 AMdata class Pet(val names: @NonNull List<@NonNull String>)
The above snippet will not put any annotation on the method, its type or type parameter. It will just compile them to @kotlin.Metadata
where they are not visible to a Java library that is not aware of Kotlin.
The Java code above compiles to
public getNames()Ljava/util/List;
@Lorg/eclipse/microprofile/graphql/NonNull;()
@Lorg/eclipse/microprofile/graphql/NonNull;() : METHOD_RETURN, 0;
@Lorg/eclipse/microprofile/graphql/NonNull;() : METHOD_RETURN, null
and I'm looking for a Kotlin data class that compiles to the same bytecode.Philip Graf
09/12/2022, 11:35 AMdata class Pet(@get:NonNull val names: List<@NonNull String>)
compiles to
public final getNames()Ljava/util/List;
@Lorg/eclipse/microprofile/graphql/NonNull;()
i.e. it puts the annotation on the method but not the type or type parameter.ephemient
09/15/2022, 1:48 AM