Java 简明教程

Java - Inner Class Diamond Operator

Java Diamond Operator

Java 7 中引入了菱形运算符,以便为 Generics 使代码更具可读性。泛型是一种类型的参数。使用泛型,我们可以将任何类型的对象传递给 class methods 处理。例如,如果我们在 Java 7 之前创建 strings 的列表,则我们必须使用以下语法来使用 ArrayList 对象实例化字符串列表。

List<String> listOfStrings = new ArrayList<String>();

从 Java 7 开始,我们可以使用菱形运算符来简化上述语法,如下所示:

List<String> listOfStrings = new ArrayList<>();

Anonymous 内部类不能使用它。例如,在 Java 9 之前,我们不能在以下语法中从菱形运算符中省略对象类型。

Handler<Integer> intHandler = new Handler<Integer>(1) {
   @Override
   public void handle() {
      System.out.println(content);
   }
};

Diamond Operator in Anonymous Class

在 Java 9 中,菱形运算符也可以与匿名类一起使用以简化代码并提高可读性。

Handler<Integer> intHandler = new Handler<>(1) {
 @Override
 public void handle() {
	System.out.println(content);
 }
};

Diamond Operator in Java 7, Java 8

在下面的示例中,我们为一个接受泛型参数的抽象类 Handler 创建匿名类,并在创建匿名类时传递对象类型,因为我们必须传递类型参数,否则程序无法编译。

Example

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();
}

Output

让我们编译并运行上述程序,这将生成以下结果 −

1
2
Test

Diamond Operator Java 9 Onwards

借助 Java 9,我们可以对匿名类使用 <> 运算符,如下所示。

Example

在以下示例中,我们为一个抽象类 Handler 创建了匿名类,该类接受一个泛型参数,但在创建匿名类时不带对象类型,因为不需要传递类型参数。编译器会自行推断类型。

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();
}

Output

让我们编译并运行上述程序,这将生成以下结果 −

1
2
Test