型の仲間達(サブクラス,スーパークラス)の取得方法
型の発見方法で取得したITypeオブジェクト。それが表す型を起点として,そのスーパークラスやサブクラス(の列挙)を取得したいことが「ごくたまに」ある。例えば,junit.framework.TestCaseクラスのサブクラスの列挙を取得することによって,Javaプロジェクト内に存在するテストクラスの一覧を得る,などである。
ある型のスーパークラスやサブクラスを取得する,という処理は,対象となる型に強く依存した機能のはずなので,当然ITypeインタフェースに規定されていると思ってしまうが,ITypeインタフェースに直接関連のあるクラスを取得できるような機能は規定されていない。その代わりに,型の継承関係を表す階層構造への操作を規定したITypeHierarchyインタフェースが存在する。
ある型を含む型の階層構造にアクセスしたいときは,ITypeインタフェースのnewTypeHierarchyメソッドを利用する。newTypeHierarchyメソッドにはいくつか種類があって,必要に応じて使い分ける。
(1) newTypeHierarchy(IJavaProject project, IProgressMonitor monitor)
- あるプロジェクトのクラスパス内に限定して,型の階層構造を構築する。
(2) newTypeHierarchy(IProgressMonitor monitor)
- ワークスペース内の全部の型を対象として,型の階層構造を構築する。
もうひとつnewTypeHierarchy(IWorkingCopy[] workingCopies, IProgressMonitor monitor)というメソッドもあるのだが,IWorkingCopyインタフェースがよくわからないので,用途不明。IWorkingCopyインタフェースのサブインタフェースとしてICompilationUnitインタフェース(Javaソースファイルを表す)があるので,特定のソース群を対象としてその中から型の階層構造を作り出すのかな,と勝手に想像するが,真相はわかりません。
newTypeHierarchyメソッドの結果のITypeHierarchyオブジェクトを得られれば,あとはgetAllSubtypesメソッドやgetAllSuperclassesメソッドを使って,サブクラスやスーパークラスのITypeオブジェクトの配列を得ることができる。
IJavaProject project = ...;
IType baseType = ...; // 型の発見方法参照
ITypeHierarchy hierarchy = baseType.newTypeHierarchy(project, null);
// スーパークラス群の取得
IType[] superclasses = hierarchy.getAllSuperclasses(baseType);
// プロジェクト内を対象にしたサブクラス群の取得
IType[] subclasses = hierarchy.getAllSubclasses(baseType);
メソッドの引数にIProgressMonitorオブジェクトがあることでもわかるように,newTypeHierarchyメソッドの実行には多くのコストが必要になる。型の継承関係を得るためには,特にサブクラスを見つけるためには,全ての型の情報を参照していかなければならないことは容易に想像つく。しかも,型の階層構造を求めなければならないことは,滅多にない。ITypeインタフェースから型の階層構造に関する処理をITypeHierarchyインタフェースに抜き出した理由は,利用頻度の少ない情報は極力ITypeインタフェースの実装に持たせないで軽くしておこうという配慮からだと思われる。
ちなみに,ある型のスーパークラス群だけを得たい(サブクラスはいらない)ときは,newSupertypeHierarchyメソッドを利用すべきである。このメソッドはnewTypeHierarchyメソッドよりも劇的にパフォーマンスはいいはず。なぜなら,スーパークラス群を求める処理は,対象となるJavaプロジェクト内に限定されるし,各型にはスーパークラスの指定が記載されているはずなので単純にその指定を追っていくだけで済むから,である。
| 固定リンク
この記事へのコメントは終了しました。
コメント