1. ジェネリックの簡単な理解
ジェネリックは Java SE 1.5 の新機能です。ジェネリックの本質はパラメータ化された型であり、操作対象のデータ型がパラメータとして指定されることを意味します。人気のポイントは「型変数」です。このタイプの変数は、クラス、インターフェイス、メソッドの作成に使用できます。
Java ジェネリックスを理解する最も簡単な方法は、Java ジェネリックスを Java キャスト操作の一部を省略できる便利な構文として考えることです。
次のようにコードをコピーします。 List<Apple> box = new ArrayList<Apple>();box.add(new Apple());Apple apple =box.get(0);
上記のコード自体は、それ自体を非常に明確に表現しています。box は Apple オブジェクトを含むリストです。 get メソッドは Apple オブジェクト インスタンスを返します。このプロセスでは型変換は必要ありません。ジェネリックスを使用しない場合、上記のコードは次のように記述する必要があります。
次のようにコードをコピーします。 Apple apple = (Apple)box.get(0);
2. ジェネリック医薬品の恥ずかしさ
ジェネリックの最大の利点は、プログラムの型安全性を提供し、下位互換性があることですが、少し冗長に感じるだけでなく、定義するたびにジェネリックの型を指定する必要があるという厄介な点もあります。明示的に指定する必要がありますが、プログラマの多くはジェネリックスに精通していないため、正しい型パラメータを提供できないことがよくあります。コンパイラがジェネリックスのパラメータ型を自動的に推論できるようになり、そのような状況が軽減され、コードが改善されます。読みやすさ。
3. Java 7 でのジェネリック型推論の改善
以前のバージョンでは、ジェネリック型を使用する場合、値を宣言および代入するときに両側にジェネリック型を追加する必要がありました。例えば:
次のようにコードをコピーします。 Map<String, String> myMap = new HashMap<String, String>();
「変数の宣言時にパラメータの型をすでに指定しているのに、オブジェクトの初期化時になぜ再度指定する必要があるのでしょう?」と思われるかもしれません。幸いなことに、Java SE 7 ではこのメソッドが改善され、次のステートメントを使用して値を宣言して割り当てることができるようになりました。
次のようにコードをコピーします。 Map<String, String> myMap = new HashMap<>(); //最後の「<>」に注意してください。
このステートメントでは、コンパイラは、変数が宣言されたときにジェネリック型に基づいて HashMap をインスタンス化するときに、ジェネリック型を自動的に推論します。繰り返しになりますが、新しい 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<>());
4. Java 8 でのジェネリック型推論の改善
Java 8 のジェネリックスのターゲット型推論には、主に 2 つのタイプがあります。
1. メソッドコンテキストを介した汎用ターゲットタイプの推論をサポート
2. ジェネリック型推論をメソッド呼び出しチェーンの最後のメソッドに渡すことをサポートします。
公式ウェブサイトから例を見てみましょう。
次のようにコードをコピーします。
クラス リスト<E> {
static <Z> List<Z> nil() { ... };
static <Z> List<Z> cons(Z head, List<Z> tail) { ... };
E head() { ... }
}
JEP101の特性上、上記のメソッドを呼び出す場合は次のように書くことができます。
次のようにコードをコピーします。
//メソッド割り当てのターゲットパラメータを通じてジェネリックの型を自動的に推測します
List<String> l = List.nil();
//指定されたタイプの代わりに表示されます
//List<String> l = List.<String>nil();
// 前のメソッドのパラメータの型からジェネリックの型を推測します
List.cons(42, List.nil());
//指定されたタイプの代わりに表示されます
//List.cons(42, List.<Integer>nil());
5. まとめ
以上がJEP101の機能内容です。Javaは静的言語の代表として豊富な型体系を持っていると言えます。型間の変換の問題は、すべての Java プログラマーを悩ませています。コンパイラーを通じて型を自動的に推論することで、複雑すぎる型変換の問題をわずかに軽減できます。 これは小さな改善ではありますが、毎日コードを書くプログラマにとっては間違いなく大きな影響を与えるでしょう。少なくとも彼らはより幸せに感じるでしょう ~~ おそらく Java 9 では、js や一部の動的言語のようなユニバーサル型 var が得られるでしょう。 scala はこんな感じです^_^