Java 8新特性のタイプ動力ノードJava学院の整理


注釈はjava 5からこの特性を加入し始めて、今まで発展してすでに至るところ花が咲いたので、多くのフレームワークの中で広範な使用を得て、プログラムの中の構成を簡略化します。その論争に満ちたタイプの注釈は一体何ですか?複雑ですか?それとも便利ですか?
どのタイプのコメントですか?
java 8の前に、注釈は声明の場所でしか使用できません。例えば、クラス、方法、属性などです。java 8の中で、注釈はどこにでも適用できます。例えば:
  • 作成クラス例    
  • 
    new @Interned MyObject();
  • タイプマッピング
  • 
        myString = (@NonNull String) str;
  • implemens文には      
  • 
    class UnmodifiableList<T> implements @Readonly List<@Readonly T> { ... }
  • throw exception声明   
  • 
     void monitorTemperature() throws @Critical TemperatureException { ... }
    注意したいのは、類型の注釈は語義ではなく文法だけで、javaのコンパイル時間、ロード時間、および運行時間に影響しない、つまり、classファイルにコンパイルする時は類型の注釈が含まれていないということです。
    タイプコメントの役割
    まず次のコードを見てください。
    
    Collections.emptyList().add("One");
    int i=Integer.parseInt("hello");
    System.console().readLine();
    上のコードのコンパイルは通っていますが、運行はそれぞれUnisportedOperation Exceptionに報告されます。Number Format Exception;Null PointerException異常、これらは全部runtime errorです。
    タイプの注釈はJavaのプログラムで強いタイプの検査をサポートするために使われます。プラグイン式のcheck frame ewarkに合わせて、コンパイル時にruntime errorを検出して、コードの品質を向上させることができます。これがタイプ注解の役割です。
    チェックフレームフレームワーク
    check frame ewarkは第三者ツールであり、Javaのタイプに合わせた注釈効果は1+1>2である。javacコンパイラに組み込むことができます。antとmavenに合わせて使用できます。eclipseプラグインとしてもいいです。住所はhttp://types.cs.washington.edu/checker-framework/です。
    check frame ewarkはタイプの注釈が現れるところを見つけて検査します。簡単な例を挙げます。
    
    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 <nulltype>
    required: @NonNull Object
        @NonNull Object ref = null;
                   ^
    1 error
    もしタイプの注釈を使ってエラーを検出したくないなら、processorは必要ありません。直接javac GetStartd.javaはコンパイルできます。これはjava 8 with Type Annotation Supportバージョンでできますが、java 5,6,7バージョンは全部だめです。javacコンパイラは知らないです。タイプをnonnullに注釈します。
    たとえば、上記の例は
    
    import checkers.nullness.quals.*;
    public class GetStarted {
      void sample() {
        /*@NonNull*/ Object ref = null;
      }
    }
    このようにjavacコンパイラは注釈ブロックを無視しますが、check frame ewarkの中のjavacコンパイラでもnonnullエラーを検出できます。
    タイプの注釈+check frame eworkによって見られます。今はruntime errorはコンパイルの時に見つけられます。
    JSR 308について
    JSR 308は、Java 1.5注釈において発生する二つの問題を解決したいです。
  • は構文で注釈に対する制限があります。注釈を声明のところに書くしかないです。 
  • タイプシステムの意味上の制限:タイプシステムはまだすべてのバグを予防することができません。 
  • JSR 308は、上記の2つの問題を以下の方法で解決する。 
    はJava言語の構文を拡張して、注釈がより多くの位置に現れることを許可します。方法受信機(method receivers,訳注:例public intessize()@Readonly{})、汎型パラメータ、配列タイプ変換、タイプテスト、オブジェクト作成、タイプパラメータバインディング、クラス継承、およびthrowsサブルーチン。実はタイプの注釈です。今はjava 8の特徴です。
    挿抜可能なタイプのシステムを導入することにより、より強力な注釈プロセッサを作成することができる。タイプの検査器はタイプ限定の注釈があるソースコードを分析しています。不一致などのエラーが発見されると警告情報が発生します。実はチェックフレームワークです。
    JSR 308に対して、反対する人がいます。もっと複雑で静的な感じがします。 
    
    @NotEmpty List<@NonNull String> strings = new ArrayList<@NonNull String>()> 
    動的言語に切り替える 
    
    var strings = ["one", "two"]; 
    賛成する人がいます。つまり、コードこそ「最も根本的」な文書です。コードに含まれる注釈はコード作成者の意図を明確に示しています。適時に更新されていない場合や遺漏があった場合は、注釈に含まれる意図情報で、他の文書の中で最も失われやすいです。また、実行時のエラーをコンパイル段階に移行することで、開発プロセスを加速するだけでなく、テスト時のバグチェックの時間を節約することができます。
    締め括りをつける
    誰もがこの特性が好きなわけではありません。特にダイナミックな言語が流行している今日、幸いにして、java 8はみんなにこの特性を使うように強要していません。反対の人はこの特性を使わなくてもいいです。コードが多くなりますが、コードの表現にもっと意味があります。この特性についてどう思いますか?