[Java] Java 8's new Type Annotations

原文はこちら。
https://blogs.oracle.com/java-platform-group/entry/java_8_s_new_type

Java 8で、2個の重要な変更をAnnotationに対して導入しました。これは、開発者がよりよいコードを書き、その品質確認のために、自動コード分析の正確性を向上するのに役立たせることを目的としています。

Quick Annotations Webinar

この新しい変更を説明する動画がJava 8 Launch Webcastで紹介されました。

Enhanced Metadata - Annotations and Access to Parameter Names (by Alex Buckley and Michael Ernst)

Annotation Improvements

Type Annotationを使うと開発者は以前よりも多くの箇所でアノテーションを使うことができます。コンパイラはこれらのアノテーションを検証できます。例えば、Null値や突発的な値の変更、適切な検証をせずにデータが信頼境界線(trust boundary)をまたがるようなケースを識別します。いくつかのアノテーション可能な情報をJavadoc(人だけが理解できる)から、コード(人にもアナライザにも理解できる)に移すことで、より簡単に意図を理解し、特定のエラーがないことを確認することができます。ラッパーアノテーションの必要性が少なくなるため、アノテーションを繰り返すことで、これらのアノテーションの作成者が楽になります。Checker Frameworkは、ライブラリ開発者やアプリケーション開発者の両者にとってメリットがあるType Annotationを提供しています。
The Checker Framework Manual: Custom pluggable types for Java
http://types.cs.washington.edu/checker-framework/current/checkers-manual.html
例えば、こんなアノテーションを提供しています。
  • @NonNull – NullPointerExceptionをデバッグしていなくても、コンパイラはコードパスがnull値を受け取る可能性があるかどうかを判断することができます。
  • @ReadOnly – コンパイラはオブジェクトを変更しようとする振る舞いに対し、フラグを立てます。Collections.unmodifiableListに似ていますが、より一般的で、コンパイル時に検証されます。
  • @Regex – 正規表現として使用することを意図したStringが正しい正規表現形式であることをコンパイル時に検証します。
  • @Taintedと@Untainted – 一緒に使われるべきではないデータタイプを識別します。例えば、システムコマンドでリモートユーザーの入力を使う、とか、機密情報をログストリームに入れる、などです。
  • @m – 測定単位は測定するオブジェクトで使われる数値が正しく使われ比較されていること、また、適切な単位変換をしていることをを保証します。

Putting Type Annotations on your code

Java SE 8を使うと、型を使っているところでType Annotationを使うことができます。以前はアノテーションは定義部にしか使えませんでした。例で説明しましょう。
Annotationの例 意味
@NonNull List<String>
String型のNullではないリスト
List<@NonNull String>
非NullではないString型のリスト
@Regex String validation = "(Java|JDK) [7,8]"
コンパイル時にこのString型が有効な正規表現であるかどうかをチェックする
private String getInput(String parameterName){
final String retval = @Tainted request.getParameter(parameterName);
  return retval;
}
retvalに割り当てられたオブジェクトは、汚染されており、機密情報の操作では使えません。
private void runCommand(@Untainted String… commands){
ProcessBuilder processBuilder = new ProcessBuilder(command);
  Process process = processBuilder.start();
}
各コマンドは汚染されていてはいけません。例えば、以前汚染されたString型は、ここに渡される前に検証する必要があります。

Automating issue detection

Type Annotationは早期に潜在的な問題を発見するのに役立ちます。早期に発見した問題は、後で発見した場合よりも修正が容易で、そして早期に発見した潜在的な問題をもまた簡単に修正できます。一部のアノテーションについては、問題をすぐに発見できます。 @Overrideアノテーションは、開発者が間違ったメソッドシグネチャを書いたかどうかをコンパイラ(または静的解析ツール)がすぐに判断します。 @NonNullと@Readonlyのようなアノテーションは、Checker Framework、FindBugs、Eclipse、NetBeans、IntelliJその他の商用アナライザのようなツールによって利用されることがあります。
The Checker Framework
http://types.cs.washington.edu/checker-framework/
FindBugs™ - Find Bugs in Java Programs
http://findbugs.sourceforge.net/
こうしたアナライザは、IDEでのバックグラウンドコンパイル、Ant/Maven、Continuous Integrationを通じて、コンパイル時に実行されます。
Maven plugin
http://types.cs.washington.edu/checker-framework/current/checkers-manual.html#maven-plugin
Type Annotationこうしたアナライザに何を探すべきかを伝える役割を果たします。所定の位置にType Annotationがなければ、これらのアナライザは、まだNullの使用箇所や書き込みの変更箇所を探しますが、その変更が間違っているかどうかはわかりません。その結果、問題なしと報告したり、誤った問題を報告する可能性があります。

Teamwork

Type Annotationは、地理的に分散したり、多くのメンバーが含まれているチームに対し、多大なメリットをもたらします。コードの中にType Annotationを配置し、コミット前や、統合ビルド中にチェックを自動化することで、ある変更が気づかぬうちに別の機能に対し影響を与えるような状況を、チームメンバーが識別することができます。

Optional Type Annotations are not a substitute for runtime validation

Type Annotation登場以前は、Null値を許容するかどうかとか、範囲などを記述するための主な場所は、javadocでした。Type Annotationでは、このコミュニケーションは、コンパイル時の検証のためにバイトコードに付属します。あなたのコードは実行時の検証を実行する必要があるのは変わりません。

Annotation validation versus Business Validation

Type Annotationsはコンピュータサイエンスに関連するバリデーションの形式で最も使われていますが、ビジネスバリデーションには対応しないことがあります。
Type Annotationに
適している要件
Type Annotationが
適切ではないと考えられる要件
Null値のチェック
数値範囲のチェック
正規表現などの基本的な型のチェック
割り当てや更新(例えば読み取り専用など)
データフロー検証の検知(例えば、関数の入力引数を正しい検証関数に流す、とか)
休日や業務時間外にこの機能を実行できないことのチェック
機能へのアクセスには特定のアカウントタイプが必要であることのチェック

Appendix

Annotations in core Java

Java SE 8プラットフォームですぐ使えるデフォルトのType Annotationはありません。このエントリでご紹介した例ではすべて、Checker Frameworkを使用していました。 Java SE 8のType Annotationは、プログラムを記述する正しい領域にアノテーションを入れることに注力しました。独立した、現在アクティブではないJSR- 305(これはJava 8に含まれていません)は、こうしたアノテーションが何であるべきかを識別するために存在します。Checker Frameworkは現在、Java Annotation Index Filesを使って、コアのJavaランタイムやターゲットライブラリ、Java SE 7や6といった以前のJavaバージョンに対し、同等のサポートを得ようとしています。
Annotation File Utilities
http://types.cs.washington.edu/annotation-file-utilities/

Removal of APT

JDK 8はレガシーのAnnotation処理ツールであるaptも削除していますが、この変更による影響は少ないと考えています。これはJEP 117の一環として実施されました。その理由は、Annotation処理に必要なものはjavax.annotation.processingもしくはjarax.lang.modelに全てあるからです。
JEP 117: Remove the Annotation-Processing Tool (apt)
http://openjdk.java.net/jeps/117

0 件のコメント:

コメントを投稿