JavaのDiamondオペレータの手引き

JavaのDiamondオペレーターのガイド

1. 概要

この記事では、diamond operator in Java and how generics and the Collections API influenced its evolutionを見ていきます。

2. 生のタイプ

Prior to Java 1.5, the Collections API supported only raw types –コレクションを構築するときに型引数をパラメーター化する方法はありませんでした。

List cars = new ArrayList();
cars.add(new Object());
cars.add("car");
cars.add(new Integer(1));

これにより、任意のタイプとled to potential casting exceptions at runtimeを追加できました。

3. ジェネリックス

Java 1.5では、オブジェクトを宣言および構築するときに、ジェネリックス(Collections APIのジェネリックスを含むwhich allowed us to parameterize the type arguments for classes)が導入されました。

List cars = new ArrayList();

この時点で、specify the parameterized type in the constructorにする必要がありますが、これは多少判読できない場合があります。

Map>>> cars
 = new HashMap>>>();

このアプローチの理由は、raw types still exist for the sake of backward compatibilityであるため、コンパイラーはこれらのraw型とジェネリックスを区別する必要があります。

List generics = new ArrayList();
List raws = new ArrayList();

コンパイラーはコンストラクターで未加工の型を使用することを引き続き許可していますが、警告メッセージが表示されます:

ArrayList is a raw type. References to generic type ArrayList should be parameterized

4. ダイヤモンドオペレーター

ダイヤモンド演算子– Java 1.7で導入–adds type inference and reduces the verbosity in the assignments – when using generics

List cars = new ArrayList<>();

Java 1.7コンパイラの型推論機能determines the most suitable constructor declaration that matches the invocation

車両とエンジンを操作するために、次のインターフェイスとクラス階層を検討してください。

public interface Engine { }
public class Diesel implements Engine { }
public interface Vehicle { }
public class Car implements Vehicle { }

ダイヤモンド演算子を使用して、Carの新しいインスタンスを作成しましょう。

Car myCar = new Car<>();

内部的には、コンパイラはDieselEngineインターフェイスを実装していることを認識しており、型を推測することで適切なコンストラクタを決定できます。

5. 結論

簡単に言えば、ダイヤモンド演算子は型推論機能をコンパイラに追加し、ジェネリックで導入された割り当ての冗長性を減らします。

このチュートリアルのいくつかの例はon the GitHub projectにありますので、ダウンロードして試してみてください。