Java 8新特性の汎型のターゲットタイプ推定_動力ノードJava学院の整理


簡単に汎型を理解する
汎型はJava SE 1.5の新しい特性であり、汎型の本質はパラメータ化タイプであり、つまり動作するデータタイプはパラメータとして指定されている。分かりやすい点は「型の変数」です。このタイプの変数はクラス、インターフェース、および方法の作成に使用できます。
Java汎型を理解する最も簡単な方法は、それを便利な文法と見なし、いくつかのJavaタイプの変換(casting)上の操作を節約することです。

List<Apple> box = new ArrayList<Apple>();
box.add(new Apple());Apple apple =box.get(0);
上のコード自体ははっきりと表現されています。boxはAppleのオブジェクトが入ったListです。get方法は、タイプ変換を必要としないAppleオブジェクトの例を返します。一般的なタイプがなく、上のコードはこう書く必要があります。

Apple apple = (Apple)box.get(0);
普通の気まずさ
泛型の最大の利点は、プログラムのタイプの安全を提供している同時に後方互換性がありますが、ばつが悪いところもあります。定義するたびに汎型のタイプを明示しています。このように指定が長いだけではなく、多くのプログラマが汎型に慣れていないため、正しいタイプのパラメータを提供できない場合が多いです。コンパイラで汎型のパラメータタイプを自動的に推定することで、このような状況を低減し、コードの可読性を向上させることができます。
java 7の汎型タイプの推論改善
以前のバージョンでは、汎型タイプを使用して、宣言し、値を賦課する際には、両側に汎型タイプを追加する必要があります。たとえば:

Map<String, String> myMap = new HashMap<String, String>();
老子は変数を宣言する時にすでにパラメータタイプを指定しました。毛のためにまだ初期化対象時に指定しますか?幸い、Java SE 7では、このような方式が改善されました。今は次のような文を使って声明し、値を付けられます。

Map<String, String> myMap = new HashMap<>(); //     "<>"
このステートメントでは、コンパイラは変数宣言時の汎型の種類から、インスタンス化されたHashMapの場合の汎型のタイプを自動的に推定します。再度注意する必要があります。new HashMapの後ろにある「<>」だけが自動的なタイプの推論であることを表します。そうでなければ、非汎型のHashMapであり、コンパイラでソースコードをコンパイルするときに警告メッセージが与えられます。
しかし、Java SE 7は、汎型インスタンスを作成する際のタイプ推定には制限があります。構造体のパラメータ化タイプだけが文脈で顕著に宣言されて、タイプ推定を使用することができます。そうでなければだめです。例えば、以下の例はjava 7では正確にコンパイルできません。(ただし、現在はjava 8でコンパイルできます。方法パラメータによって汎型のタイプが自動的に推定されますので)

List<String> list = new ArrayList<>();
list.add("A");//   addAll    Collection<? extends String>     ,           
list.addAll(new ArrayList<>());
Java 8の汎型タイプの推論改善
java 8における汎型のターゲットタイプの推論は主に2つである。
1.一般的なターゲットタイプは、方法コンテキストで推論することをサポートします。
2.方法によるリンクの呼び出しにおいて、汎型推論は最後の方法に伝達されることをサポートする。
公式サイトの例を見てみましょう。

class List<E> {
  static <Z> List<Z> nil() { ... };
  static <Z> List<Z> cons(Z head, List<Z> tail) { ... };
  E head() { ... }
}
   JEP 101の特性によって、上記の方法を呼び出す時にこのように書いてもいいです。

//                     
List<String> l = List.nil();
//          
//List<String> l = List.<String>nil();
//                 
List.cons(42, List.nil());
//          
//List.cons(42, List.<Integer>nil());
締め括りをつける
以上はJEP 101の特性内容ですが、Javaは静的言語の代表者として、かなり豊富なタイプのシステムと言えます。タイプ間の相互変換を引き起こす問題は、Javaプログラマーそれぞれに迷惑をかけています。コンパイラでタイプを自動的に推論することによって、タイプの変換が複雑すぎる問題を少し緩和することができます。ちょっと進歩したとは言え、毎日コードを書いているプログラマーにとっては、きっと大きな効果をもたらしてくれます。少なくとも気持ちがいいです。JAVA 9の中には、汎用的なタイプのvarがあります。jsやscalaのような動的言語があります。