I want to create an option class that holds a key-value structure.
This Map is filled with the content of a configuration file at runtime.
To validate that Config I want do define required keys per annotation of the Option class like:
// Map must contain a entry with key 'foo' and key 'bar'
@requiredKey("foo")
@requiredKey("bar")
class Options {
Map<String, String> optionsMap;
}
Therefore I created a repeatable annotation:
@Retention(RetentionPolicy.RUNTIME)
public @interface requiredKeys {
requireKey[] value();
}
@Repeatable(requiredKeys)
public @interface requredKey {
String value();
}
At runtime I call requiredKey[] anno = options.getAnnotationsByType(requiredKey.class))
This works fine if the number of specified annotations is > 1. But if the number of annotations is exactly one, I cant obtain it (getAnnotationsByType
returns an empty array)
working:
@requiredKey("foo")
@requiredKey("bar")
class Options {
Map<String, String> optionsMap;
}
// anno holds 'foo' and 'bar'
requiredKey[] anno = options.getAnnotationsByType(requiredKey.class))
not working:
@requiredKey("foo")
class Options {
Map<String, String> optionsMap;
}
// anno is empty
requiredKey[] anno = options.getAnnotationsByType(requiredKey.class))
I don't understand this behaviour :(
So my Questions are:
Thanks
You need to add to your @requiredKey
the retention policy:
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(requiredKeys)
public @interface requredKey {
String value();
}
If you don't, then when you create a class with one annotation, Java does not create a requiredKeys
annotation because you have only one Annotation
. Therefor, the retention policy of the @requiredKey
is applied. In your case, you had none, which means that your annotation won't be visible by the JVM.
Other comments: Please use Capital letter for your class/annotations.
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredKeys {
requireKey[] value();
}
@Repeatable(RequiredKeys)
public @interface RequiredKey {
String value();
}