Search code examples
javaannotationscode-generationbytecode-manipulationannotation-processing

Generate code that implements JSR 308 "instanceof @MyAnotations" runtime check


JSR 308 proposes to add type annotations to Java. After its ratification, programmers will be able to add an annotation wherever a Java type is currently allowed. That includes not only method/field/local/parameter decorations, but also constructor calls, type casts, and most curiously instanceof checks. The Checker Framework uses JSR 308 to implement type qualifiers like @NonNull on object types, or @Regex on strings.

Now all what Checkers does is to statically analyze your code. That's all compile time checks. That's fine. But what I want to have is a mechanism that can do checks at runtime. You can declare:

@Regex String p1 = "[a-z]+";
@Regex String p1 = "[a-z)+";    // compile time error from annotation processor

I can also write:

if (x instanceof @Regex String) ...

but that is no different from x instanceof String, no runtime check is performed. I need a compile time annotation processor or runtime bytecode manipulator that lets me run arbitrary code on instanceof checks and return a boolean. Is this possible with Java?


Solution

  • Yes you can. But its not trivial and not supported by annotation processors accessible API. The accessible Annotation Processor API is limited to generate new classes and is not allowed to modify existing bytecodes (even in JDK 8). You could cast to compiler specific classes at annotation processor level, which enables a lot more options. But you would have to use the compilers internal API and rewrite it for each compiler available (JDT and JavaC). You may take a look at project Lombok (http://projectlombok.org/) which does a very similar thing. Sadly Lombok is not yet compatible with JDK8s new type anntotations.