Java Annotation Processing - Purpose and Examples

Even having a good time, I cannot understand the purpose of processing annotations.

I understand why annotations are required for runtime, with the simplest example I might think:

  • Replacing the marker interface.
  • Replacing market type properties (e.g., transient)
  • In general, any utility that can be executed at runtime.

But, unfortunately, I could not understand the practical example / reasons for using annotations at compile time (except for the default annotations provided by the JDK, e.g. @Override etc.).

I could not understand what the purpose / need for "code generation" was with annotation handlers.

Edit: Javadoc / Custom Java doc is one utility that I can see as the goal of using annotation handlers.

+4
source share
2 answers

It can be used for all kinds of things.

Two simple examples

  • Lombock project . Tired of writing thousands of getters and setters? Why not let the annotation processor do this at compile time.
  • AOP . You can use something like AspectJ to weave in annotation dependent code. This will be done after compilation, but as part of the compilation process. For example, Spring AOP uses the @Transactional annotation in conjunction with AspectJ to weave transaction code around methods marked with the annotation.

There are many other uses, but they usually fall into two categories.

  • To reduce the boiler plate code.
  • For cross-cutting issues.
+4
source

There are two main goals of the annotation processing environment - analysis and code generation.

Analysis allows you to expand the capabilities of the java compiler by analyzing program elements as they are compiled, possibly adding additional restrictions, checks and error messages and warnings about violations of these restrictions.

Code generation allows you to generate additional additional code from signals in your existing handwritten code, mostly (though not exclusively) with annotations.

Some examples include Dagger , which is a system for analyzing dependencies at compile time, error messages and warnings that typically occur at runtime instead during compilation of code. The dagger also generates all the code that would normally be executed by reflection, or by manually writing a glue code that provides significant performance benefits (in some cases), as well as infrastructure code that is available for end-to-end debugging, etc.

Another example is the Checker Framework , which evaluates a lot of checks of your code, including zero security, etc.

The third Auto-Value example is designed to make small types of values ​​almost trivial to write.

One of the conditions for which the annotation processing environment is definitely not suitable is a mutation of the existing code in place or a change in the code that is currently in the process of compilation. Although some projects do this, they do not actually use the annotation processor APIs, but rather for internal compiler types. Although this is clearly possible, it is potentially fragile and may not work reliably from version to version or compiler to compiler, requiring special handling for each version and compiler provider.

+1
source

Source: https://habr.com/ru/post/1484030/


All Articles