前回紹介したように,アノテーション処理はルート要素から順々と要素を取得して処理を進めていきます。しかし,処理の過程でif文が多いのが気になるところでした。

そこで,今回はなるべくif文を使わずに処理を進める方法を紹介します。キーとなるのはデザインパターンのビジタパターンです。

ビジタパターンによるアノテーション処理

ビジタパターンは特定のクラスに触ることなく機能を追加するために使用されます。

一般的に,ビジタを受け入れる,つまり何らかの機能追加を行いたいクラスはacceptメソッドを定義しておきます。そして,acceptメソッドの中でビジタのvisitメソッドをコールするようにします。ビジタのvisitメソッドには追加したい処理を記述します。

このような使い方はアノテーション処理でも同様です。アノテーション処理の場合,要素を表すjavax.lang.model.element.Elementインタフェース,型を表すjavax.lang.model.type.TypeMirrorインタフェースがビジタを受け入れるためのacceptメソッドを定義しています。

一方のビジタとして,要素を訪問するjavax.lang.model.element.ElementVisitorインタフェース,型を訪問するjavax.lang.model.type.TypeVisitorインタフェースが提供されています。

これらのビジタはvisitメソッドだけでなく,その要素や型に応じたメソッドが定義されています。例えば,ElementVisitorインタフェースでは要素が型の場合コールされるvisitTypeメソッドが定義されています。これらの個々の要素や型に応じたメソッドを実装することでif文を使わずに要素や型に応じた処理を行うことができます。

実際にはこれらのビジタインタフェースを直接使うのではなく,ビジタインタフェースを実装したクラスを使用します。例えば,ElementVisitorインタフェースを実装したクラスにはjavax.lang.model.util.SimpleElementVisitor6クラス,もしくはjavax.lang.model.util.ElementKindVisitor6クラスがあります。これらのクラス名の最後の6はJava SE 6のソースバージョンに対応していることを示しています。

では,これらのクラスを使ってみましょう。使用するアノテーションは前回と同じ,AbstractionアノテーションとAbstractionMethodアノテーションです。

サンプルのソース (こちらからダウンロードできます)
Abstraction.java
AbstractionMethod.java
VisitorProcessor.java