Java Diamond Operator:Java 7+ でのジェネリックスの簡素化
Java ダイヤモンド オペレーター
ダイヤモンド演算子は、ジェネリック向けにコードを読みやすくするために Java 7 で導入されました。ジェネリックは引数の一種です。ジェネリックを使用すると、クラス メソッドで処理されるあらゆる種類のオブジェクトを渡すことができます。たとえば、Java 7 より前の文字列のリストを作成する場合は、次の構文を使用して、ArrayList オブジェクトで文字列のリストをインスタンス化する必要があります。
List<String> listOfStrings = new ArrayList<String>();
Java 7 以降では、ダイヤモンド演算子を使用して上記の構文を次のように簡略化できます。-
List<String> listOfStrings = new ArrayList<>();
ただし、匿名の内部クラスでは使用できませんでした。たとえば、Java 9 より前の以下の構文では、ダイヤモンド演算子からオブジェクト タイプを省略できません。
Handler<Integer> intHandler = new Handler<Integer>(1) {
@Override
public void handle() {
System.out.println(content);
}
};
匿名クラスのダイヤモンド オペレーター
Java 9 では、ダイヤモンド演算子を匿名クラスでも使用して、コードを簡素化し、読みやすさを向上させることができます。
Handler<Integer> intHandler = new Handler<>(1) {
@Override
public void handle() {
System.out.println(content);
}
};
Java 7、Java 8 のダイヤモンド演算子
以下の例では、ジェネリック引数を受け入れる抽象クラス ハンドラーの匿名クラスを作成し、型引数を渡す必要があるため、匿名クラスの作成中にオブジェクト型を渡します。そうしないとプログラムはコンパイルできません。
例
public class Tester {
public static void main(String[] args) {
// create an Anonymous class to handle 1
// Here we need to pass Type arguments in diamond operator
// before Java 9 otherwise compiler will complain error
Handler<Integer> intHandler = new Handler<Integer>(1) {
@Override
public void handle() {
System.out.println(content);
}
};
intHandler.handle();
// create an Anonymous class to handle 2
Handler<? extends Number> intHandler1 = new Handler<Number>(2) {
@Override
public void handle() {
System.out.println(content);
}
};
intHandler1.handle();
Handler<?> handler = new Handler<Object>("test") {
@Override
public void handle() {
System.out.println(content);
}
};
handler.handle();
}
}
abstract class Handler<T> {
public T content;
public Handler(T content) {
this.content = content;
}
abstract void handle();
}
出力
上記のプログラムをコンパイルして実行してみましょう。これにより、次の結果が生成されます-
1 2 Test
Diamond Operator Java 9 以降
Java 9 では、以下に示すように、匿名クラスで <> 演算子を使用できます。
例
以下の例では、ジェネリック引数を受け入れる抽象クラス ハンドラーの匿名クラスを作成しましたが、型引数を渡す必要がないため、匿名クラスの作成中にオブジェクト型は使用しませんでした。コンパイラは型自体を推論します。
public class Tester {
public static void main(String[] args) {
// create an Anonymous class to handle 1
// Here we do not need to pass Type arguments in diamond operator
// as Java 9 compiler can infer the type automatically
Handler<Integer> intHandler = new Handler<>(1) {
@Override
public void handle() {
System.out.println(content);
}
};
intHandler.handle();
Handler<? extends Number> intHandler1 = new Handler<>(2) {
@Override
public void handle() {
System.out.println(content);
}
};
intHandler1.handle();
Handler<?> handler = new Handler<>("test") {
@Override
public void handle() {
System.out.println(content);
}
};
handler.handle();
}
}
abstract class Handler<T> {
public T content;
public Handler(T content) {
this.content = content;
}
abstract void handle();
}
出力
上記のプログラムをコンパイルして実行してみましょう。これにより、次の結果が生成されます-
1 2 Test
Java