Annotation Type GenerateVisitor


@API(INTERNAL) @Target(TYPE) @Retention(CLASS) public @interface GenerateVisitor
Annotation to cause the annotation processor GenerateVisitorAnnotationProcessor to create a visitor for all implementors of an interface or all subclasses of a root class that can be discovered in the current compilation unit. The generated visitor interface contains an overloaded visit method per discovered implementor/subclass and a polymorphic method T visit(element) that dispatches to the right visitation method for the element that is passed in. The interface that is generated should be implemented by all visitors visiting the class hierarchy. Motivation: The visitor design pattern can be immensely useful if used wisely. In essence, the visitor design pattern allows for multiple dispatch over two (and if needed) more subjects by chaining single dynamic dispatch on selfish methods. Furthermore, it allows the user to write code that is specific to subclasses of a hierarchy inside the visitor rather than scattering that same code over many subclasses/implementors in the form of overrides. Using the visitor design pattern in Java may cause some boilerplate which in turn may turn out to be error-prone and not maintainable:
  • A code maintenance problem usually arises over time when the visitor pattern is employed as class hierarchies are modified, new implementors are added, so it would be useful to get a compiler error if a visitor has not implemented a visitation method (yet).
  • The accept method of the visitor has to be written in the form of overrides inside the original class hierarchy. Again, it's tedious to do that (and maintain it) for the visitor/class pair.
This annotation can be used on any class or interface. When found annotating a type SomeRootClass, an interface called SomeRootClassVisitor<T> is generated which defines a method
 
    T visitSpecificClass(SpecificClass element);
 
 
for each subclass/implementor and returns some generic type T. This generated interface needs to be implemented by the user. If the hierarchy of classes is changed in some way, the visitor interface (which would be regenerated by the build process) potentially causes compilation errors if implementations of the visitor interface have not (yet) been adapted to that change. In addition to the specific visitation methods there is a method
 
    T visit(SomeRootClass element);
 
 
which when called on an element dispatches to the right override based on the dynamic type of element. That eliminates the need for writing accept methods.
  • Element Details

    • classSuffix

      String classSuffix
      .
      Returns:
      suffix of the generated visitor interface
      Default:
      "Visitor"
    • methodPrefix

      String methodPrefix
      .
      Returns:
      prefix of all visitation methods
      Default:
      "visit"
    • stripPrefix

      String stripPrefix
      .
      Returns:
      prefix we should attempt to remove from every discovered subclass when creating the name for the specific visitation method
      Default:
      ""