java11新特性—局部变量类型推断的升级

Java 11 对 本地变量类型推断(Local Variable Type Inference) 进行了扩展,这是对 Java 10 中引入的 ​​var​​​ 关键字功能的进一步增强。虽然 Java 11 并没有在语言层面增加新的语法,但它改进了 ​​var​​ 在某些场景下的使用方式,特别是与 Lambda 表达式结合时的行为

本地变量类型推断

在 Java 10 中,​​var​​ 关键字被引入,允许开发者在声明局部变量时省略显式的类型声明,编译器会根据右侧表达式的类型自动推断出变量的类型。这使得代码更加简洁

// 使用显式类型
String name = "Alice";

// 使用 var 推断类型
var name = "Alice"; // 编译器推断为 String

虽然 ​​var​​ 的引入简化了代码,但在 Java 10 中,它不能直接用于 Lambda 表达式的参数

Lambda 参数中的 ​​var​​

Java 11 允许在 Lambda 表达式的参数中使用 ​​var​​,从而使代码更具一致性,尤其是在需要给 Lambda 参数添加注解或修改修饰符时非常有用

// Java 10 中无法使用 var
(String s) -> s.length();

// Java 11 中可以使用 var
(var s) -> s.length();
  • ​(var s)​ 是合法的,编译器会推断出 ​s​ 的类型。
  • 使用 ​var​ 使得 Lambda 表达式的参数声明风格与其他地方的变量声明保持一致

Lambda 参数支持注解

如果你需要在 Lambda 参数上添加注解(例如 ​@NonNull​),使用 ​var​ 是唯一的选择

import org.jetbrains.annotations.NotNull;

(var s) -> {
@NotNull var result = s.toUpperCase();
return result;
};

限制和注意事项

  1. lambda表达式中,注解修饰变量的时候,变量的数据类型必须要写,不能省略,像下面这种写法就是错误的
Consumer<String>con =(@Deprecated t)->System.out.println(t.toLowerCase()); // 错误语法
Consumer<String>con =(@Deprecated String t)->System.out.println(t.toLowerCase()); //正确写法
  1. java11中,lambda表达式中的参数数据类型可以使用var,但是不能不写
Consumer<String>con =(@Deprecated var t)->System.out.printin(t.toLowerCase());
  1. var修饰符不能与其他参数混合使用。以下将抛出编译错误
BinaryOperator<Integer> bo2 = (var value1, value2) -> value1 + value2; // 错误语法
  1. var修饰符不能与其他类型参数混合使用。以下将抛出编译错误
BinaryOperator<Integer> bo3 = (var value1, Integer value2) -> value1 + value2; // 错误语法
  1. var修饰符只能与括号一起使用。以下将抛出编译错误
Consumer<Integer> consumer = var value1 -> System.out.println(value1); // 错误语法