I'm guessing what you're wanting is to have a method like
public void callFoo(Class<?> clazz)
and you want to ensure that clazz
has a method public static void foo()
.
I thought about this a while and none of the techniques that come to mind will get you there. You can use an AnnotationProcessor
to ensure that any classes annotated with a certain annotation have a specific method or what have you (and generate a compile error if they don't) but there's no way to ensure (at compile time) that Class
arguments passed to callFoo(Class<?> clazz)
are annotated with your annotation.
Here's an AnnotationProcessor that gets you halfway there:
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes("so.Foo")
public class FooAnnotationProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
TypeElement foo = processingEnv.getElementUtils().getTypeElement("so.Foo");
Set<? extends Element> classes = roundEnv.getElementsAnnotatedWith(foo);
Messager messenger = processingEnv.getMessager();
for (Element e : classes) {
boolean found = false;
for (Element method : e.getEnclosedElements()) {
messenger.printMessage(Diagnostic.Kind.ERROR,
method.getSimpleName());
if (method.getKind() == ElementKind.METHOD && method.getSimpleName().toString().equals("getInstance")) {
found = true;
break;
}
}
if (!found)
{
messenger.printMessage(Diagnostic.Kind.ERROR,
"The following class does not implement getInstance : " + e.getSimpleName(),e);
}
}
return true;
}
}
Ultimately, I would suggest you either allow it to be something enforced at runtime or your redesign your code so you don't need to use static methods.