Java 8の新しいプロパティのタイプ注記_ダイナミックノードJavaアカデミー整理

3840 ワード

注記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つの問題を解決する.
  • 文法上の注釈に対する制限:注釈を声明の場所に書くしかない 
  • タイプシステムの意味上の制限:タイプシステムはまだすべてのバグを予防することができません 

  • 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を採用することができます.結局、コードこそ「最も基本的な」ドキュメントです.この言葉には賛成です.コードは増えますが、コードをより表現することができます.この特性についてどう思いますか.皆さんはそれぞれ自分の意見を述べます...