At first when you asked, I immediately remembered my own experiences creating annotations, and how frustrated I was when trying to create a note that had a validation against its possible values, so my first response, which is in below, contemplates only the alternatives that I myself adopted at the time, which would be to use a different version of the compiler and / or validate the values of annotations in Runtime with unchecked Exceptions. Investigating further, I discovered a feature of the Java SE platform available from version 1.6
Annotation Processor - Java 1.6 or >
Available from version 1.6, an API that renders annotations that you define to be validated at compile time through a Processor
interface and an Abstract class AbstractProcessor
How does it work?
Firstly, you do not need any third-party libraries, plugins or artifacts, just write your own processor and use it when compiling / processing your classes that have annotations. In it you define which annotations you want to process, and whatever happens, you can even stop the compilation if it does not comply with your contracts, issue warnings, or generate codes. It is possible to have more than one Processor. Using a design cycle control tool such as Maven you will be able to apply your processors.
So let's go to your case
You want to validate the values attribute, can not have empty or null strings, can not have an empty array, with length == 0
The class below, it does the job! It is in the default package (without package defined) to facilitate understanding and testing
import java.util.Set;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes(value={"Ordem"})
public class MandatoryValuesAnnotationProcessor extends javax.annotation.processing.AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
System.out.println("/n/n Processing... /n Processing /n");
Messager messager = processingEnv.getMessager();
for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(Ordem.class)){
TypeElement typeElement = (TypeElement)annotatedElement;
Ordem ordemAnnotation = typeElement.getAnnotation(Ordem.class);
String valores[] = ordemAnnotation.valores();
if(valores == null || valores.lenght == 0){
messager.printMessage(Diagnostic.Kind.ERROR, "Annotation Ordem nao pode ter valores vazios, nao pode ser um array vazio");
return true;
}
for (String valor : valores) {
if(valor == null || valor.isEmpty()){
messager.printMessage(Diagnostic.Kind.ERROR, "Annotation Ordem nao pode ter strings vazias ou nulas");
return true;
}
}
}
return true;//because we don't want other processors to process this annotations
}
@Override
public SourceVersion getSupportedSourceVersion(){
return SourceVersion.latestSupported();
}
}
Above we are defining the Processor for your classes with your annotation, below, we use it, already compiled to process your classes.
Compile your annotation Order first, if you sequence compile the processor, and then use it to compile the other classes, as you can see, this is not the best way to manage your compilation clicks so I recommend that you use Maven to build your project, or another solution. You can also create a jar with your processor, here is where I learned:
link
For teaching purposes, use this command line when compiling your classes (you can use Maven as well)
javac -cp . -Xlint:processing -processor MandatoryValuesAnnotationProcessor -proc:only Foo2.java
Read this reference for a more complete understanding
Reference
-
Note: From the original response, it is still valid to use a prepared compiler, which is not the best because it gives you less flexibility and you can also validate annotation attribute values in Runtime, which is common on the SE platform and EE in some APIs, such as JAX-WS , for example
Original Answer
No, it is not possible Geison, at least not working only with the Oracle HotSpot compiler, there are alternative ways, such as creating your own compiler, or customizing one of OpenJDK .
I have tried to do this that you want to do, in addition to other things.
What you can do as an alternative is to write a unit test with JUnit that uses Reflection , checks the values defined for this annotation, not allowing arrays empty or Empty strings.
What I always did was when I need to read the annotation values, if they are mandatory, I throw an exception - IllegalArgumentException
Where I notice the programmer that the set value can not be null or empty.