Java 11 新特性之 本地变量类型推断扩展

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


什么是本地变量类型推断?

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

示例(Java 10):

ini 复制代码
// 使用显式类型
String name = "Alice";

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

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


Java 11 的扩展:Lambda 参数中的 ​​var​

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

示例:

scss 复制代码
// Java 10 中无法使用 var
(String s) -> s.length();

// Java 11 中可以使用 var
(var s) -> s.length();

解释:

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

为什么需要在 Lambda 参数中使用 ​​var​​?

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

示例:

ini 复制代码
import org.jetbrains.annotations.NotNull;

(var s) -> {
    @NotNull var result = s.toUpperCase();
    return result;
};
  1. 统一代码风格 : 在复杂的 Lambda 表达式中,使用 ​var​ 可以使代码风格更加统一,避免显式类型声明带来的冗长。
  2. 未来兼容性 : 随着 Java 的不断发展,​var​ 的使用范围可能会进一步扩展。提前适应这种风格有助于未来的代码迁移。

限制和注意事项

  1. 不能混合使用显式类型和 ​var​: 在 Lambda 表达式中,所有参数要么都使用显式类型,要么都使用 ​var​,不能混用。

错误示例:

javascript 复制代码
(String s, var t) -> s + t; // 编译错误
  1. 不能省略括号 : 即使只有一个参数,如果使用了 ​var​,括号也不能省略。

正确示例:

scss 复制代码
(var s) -> s.length(); // 必须加括号
  1. 不适用于方法引用 : 方法引用中不能使用 ​var​

错误示例:

javascript 复制代码
Function<String, Integer> func = (var s) -> s.length(); // 正确
Function<String, Integer> func = String::length;        // 正确
Function<var, Integer> func = String::length;          // 编译错误

实际应用示例

以下是一些实际使用场景,展示了 ​​var​​ 在 Lambda 表达式中的作用:

示例 1:带注解的 Lambda 参数

ini 复制代码
import org.jetbrains.annotations.NotNull;

(var s) -> {
    @NotNull var upper = s.toUpperCase();
    System.out.println(upper);
};

示例 2:多参数 Lambda 表达式

css 复制代码
(var a, var b) -> a + b;

示例 3:复杂逻辑的 Lambda 表达式

csharp 复制代码
(var input) -> {
    if (input == null) {
        throw new IllegalArgumentException("Input cannot be null");
    }
    return input.length();
};

总结

Java 11 对 ​​var​​ 的扩展使得它可以在 Lambda 表达式的参数中使用,从而增强了代码的灵活性和一致性。尽管这一特性在大多数情况下并不是必需的,但在需要添加注解或希望保持代码风格统一的情况下,它是非常有用的。

相关推荐
smileNicky10 小时前
SpringBoot系列之从繁琐配置到一键启动之旅
java·spring boot·后端
David爱编程10 小时前
为什么必须学并发编程?一文带你看懂从单线程到多线程的演进史
java·后端
long31611 小时前
java 策略模式 demo
java·开发语言·后端·spring·设计模式
rannn_11112 小时前
【Javaweb学习|黑马笔记|Day1】初识,入门网页,HTML-CSS|常见的标签和样式|标题排版和样式、正文排版和样式
css·后端·学习·html·javaweb
柏油12 小时前
Spring @Cacheable 解读
redis·后端·spring
柏油13 小时前
Spring @TransactionalEventListener 解读
spring boot·后端·spring
两码事14 小时前
告别繁琐的飞书表格API调用,让飞书表格操作像操作Java对象一样简单!
java·后端
shark_chili15 小时前
面试官再问synchronized底层原理,这样回答让他眼前一亮!
后端
灵魂猎手15 小时前
2. MyBatis 参数处理机制:从 execute 方法到参数流转全解析
java·后端·源码
易元15 小时前
模式组合应用-桥接模式(一)
后端·设计模式