Java 8新特性探究(4):タイプ注釈が複雑か便利か


注記java 5からこの特性を加え始め、現在に至るまで広く開花し、多くのフレームワークで広く使用され、プログラムの構成を簡素化していることはよく知られています.議論に満ちたタイプの注釈はいったい何なのか.複雑ですか、それとも便利ですか.
タイプ注記とは
Java 8の前に、注釈は宣言された場所でしか使用できません.例えば、クラス、メソッド、属性などです.JAva 8では、注釈はどこにでも適用できます.例えば、次のようにします.
  • クラスインスタンス
  • を作成する
    new @Interned MyObject();
  • タイプマッピング
  • myString = (@NonNull String) str;
  • implements文の
  • class UnmodifiableList implements @Readonly List { ... }
  • throw exception声明
  • void monitorTemperature() throws @Critical TemperatureException { ... }
    タイプ注記は、意味ではなく構文にすぎず、javaのコンパイル時間、ロード時間、および実行時間には影響しません.つまり、classファイルにコンパイルするときにタイプ注記は含まれません.
    タイプ注記の役割
    まず次のコードを見てみましょう
    Collections.emptyList().add("One"); 
    int i=Integer.parseInt("hello"); 
    System.console().readLine();

    上のコードコンパイルはパスしましたが、実行はそれぞれUnsupportedOperationExceptionに報告されます.NumberFormatException;NullPointerException異常、これらはruntime errorです.
    タイプ注記は、Javaのプログラムで強力なタイプチェックをサポートするために使用されます.プラグイン式のcheck frameworkに合わせて、コンパイル時にruntime errorを検出し、コード品質を向上させることができます.これがタイプ注釈の役割です.
    check framework
    check frameworkはサードパーティ製のツールで、Javaのタイプに合わせて注釈する効果は1+1>2です.javacコンパイラに埋め込み、antやmavenと組み合わせて使用したり、eclipseプラグインとして使用したりすることができます.住所はhttp://types.cs.washington.edu/checker-framework/.
    check frameworkは、タイプ注釈が表示される場所を見つけてチェックし、簡単な例を挙げます.
    import checkers.nullness.quals.*; 
    public class GetStarted { 
        void sample() { 
            @NonNull Object ref = new Object(); 
        } 
    }

    Javacを使用して上のクラスをコンパイルする
    javac -processor checkers.nullness.NullnessChecker GetStarted.java

    コンパイルはパスしましたが、
    @NonNull Object ref = null;

    再コンパイルすると、
    GetStarted.java:5: incompatible types. 
    found   : @Nullable  
    required: @NonNull Object 
            @NonNull Object ref = null; 
                                  ^ 
    1 error

    タイプ注記を使用してエラーを検出したくない場合は、processorは必要ありません.直接javac GetStarted.javaはコンパイルできます.これはjava 8 with Type Annotation Supportバージョンでは可能ですが、java 5,6,7バージョンではだめです.javacコンパイラは@NonNullが何なのか分かりませんが、check frameworkには下向きの互換性のある解決策があります.タイプ注記nonnullを/**/で注記することです
    たとえば、上記の例を
    import checkers.nullness.quals.*; 
    public class GetStarted { 
        void sample() { 
            /*@NonNull*/ Object ref = null; 
        } 
    }

    これによりjavacコンパイラはコメントブロックを無視しますが、check frameworkのjavacコンパイラでもnonnullエラーを検出できます.
    タイプ注記+check frameworkではruntime errorがコンパイル時に見つかるようになりました.
    JSR 308について
    JSR 308は、Java 1.5注釈で発生する2つの問題を解決する.
  • 文法上の注釈に対する制限:注釈を声明の場所
  • に書くしかない.
  • タイプシステムの意味上の制限:タイプシステムはまだすべてのbug
  • を予防することができません
    JSR 308は、上記2つの問題を以下の方法で解決する.
  • Java言語の構文を拡張し、注釈をより多くの場所に表示できるようにします.メソッド受信機(method receivers,訳注:例public int size()@Readonly{...})、汎用パラメータ、配列、タイプ変換、タイプテスト、オブジェクト作成、タイプパラメータバインド、クラス継承、throws句を含む.実はタイプ注釈で、今java 8の1つの特性
  • です
  • は、プラグイン可能なタイプのシステム(pluggable type systems)を導入することによって、より強力な注釈プロセッサを作成することができる.タイプインスペクタは、タイプ限定注釈付きのソースコードを解析し、一致しないなどのエラーが検出されると警告情報を生成します.実はcheck framework
  • です
    JSR 308に対して、ある人は反対して、更に複雑で更に静態だと感じて、例えば
    @NotEmpty List strings = new ArrayList()>

    動的言語に変換
    var strings = ["one", "two"];

    コードこそ「最も根本的な」ドキュメントだと賛成する人もいる.コードに含まれる注釈は、コード作成者の意図を明確に示している.タイムリーな更新や漏れがない場合は、注釈に含まれる意図情報であり、他のドキュメントで最も失われやすい.また、実行時のエラーをコンパイルフェーズに移行することで、開発プロセスを加速させるだけでなく、テスト時にバグをチェックする時間を節約できます.
    まとめ
    誰もがこの特性が好きなわけではありません.特にダイナミック言語が流行している今日、幸いなことにjava 8はこの特性を強要していません.反対する人はこの特性を使わなくてもいいですが、コードの品質に要求が高い人や会社はJSR 308を採用することができます.結局、コードこそ「最も基本的な」ドキュメントです.この言葉には賛成です.コードは増えますが、コードをより表現することができます.この特性についてどう思いますか.皆さんはそれぞれ自分の意見を述べます...