挖到了 1 个 Java 小特性:var,用完就回不去了

大家好,我是大华。

写 Java 这么多年,我以前是几乎不用 var 这个关键字的。看到 var 下意识就会联想到 JavaScript,这种类型模糊、不受控制的感觉,让人很不放心。

Java 的 var 是 Java10 引入的局部变量类型推断,只能用在方法内部,编译期就能确定类型,本质还是强类型语言。

最常见的写法差异,可以看看下面这个对比。

基础泛型声明

不用 var:

java 复制代码
Map<String, List<CustomerRecord>> customersByRegion = new HashMap<>();

使用 var:

java 复制代码
var customersByRegion = new HashMap<String, List<CustomerRecord>>();

类型并没有消失,只是从左边挪到了右边,而且右边往往写得更完整、更直观。


Stream 场景,对比最明显

以前写 Stream,经常是这样:

java 复制代码
Map<Long, List<OrderItemDTO>> orderItemMap = orderList.stream()
                 .filter(item -> item.getPrice() > 0)
                 .collect(Collectors.groupingBy(OrderItemDTO::getOrderId));

逻辑本身并不复杂,但左边那一串类型,其实对理解代码帮助不大。

换成 var:

java 复制代码
var orderItemMap = orderList.stream()
                 .filter(item -> item.getPrice() > 0)
                 .collect(Collectors.groupingBy(OrderItemDTO::getOrderId));

阅读代码的时候,注意力会自然的落在 filter 和 groupingBy 在做什么,而不是在解析泛型结构。


链式调用 + 中间变量

再看一个业务代码场景。

不用 var:

java 复制代码
Optional<UserProfileDTO> userProfileOptional =
        userService.getUser(userId)
                   .flatMap(user -> profileService.getProfile(user));

使用 var:

java 复制代码
var userProfileOptional =
        userService.getUser(userId)
                   .flatMap(user -> profileService.getProfile(user));

这种情况下,变量的语义已经由方法名决定了,重复写一遍 Optional<UserProfileDTO>,更多是形式上的完整,而不是信息上的必要。


try-with-resources 场景

var 在资源管理里也很好用,尤其是 IO、数据库相关代码。

java 复制代码
try (var inputStream = new FileInputStream(file);
     var reader = new BufferedReader(new InputStreamReader(inputStream))) {

    return reader.readLine();
}

类型清晰、代码紧凑,而且完全不影响可读性。


重构友好这一点,真的很实用

假设原来是这样:

java 复制代码
List<UserDTO> users = userService.getUsers();

后来需求变了,返回值改成:

java 复制代码
List<UserVO>

不用 var 的情况下,你要改这里:

java 复制代码
List<UserVO> users = userService.getUsers();

用 var 的情况下:

java 复制代码
var users = userService.getUsers();

你只需要改方法返回类型,变量声明这一行甚至不用动,这在大项目里非常舒服。


什么时候我不会用 var

我自己给自己定了几个禁用规则:

java 复制代码
// 不允许:没有初始化
var count;

// 不推荐:类型不直观
var result = service.process(a, b, c);

// 推荐:类型一眼可见
var list = new ArrayList<UserDTO>();
var map = new HashMap<String, Integer>();

var 不是为了省几个字符,而是为了减少重复的代码。如果觉得代码不好理解,那还是需要老老实实的把类型写完整。

本文首发于公众号:程序员大华,专注前端、Java开发,AI应用和工具的分享。关注我,少走弯路,一起进步!

相关推荐
_Evan_Yao6 小时前
Redis 缓存穿透、击穿、雪崩,一次讲清!
java·spring·mybatis
梓豪csd6 小时前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节
秋饼6 小时前
Spring AI 2.1 Message Parts 深度实战:推理签名回放与跨轮记忆持久化的源码级落地
java·ai·技术分享·后端开发
王中阳Go6 小时前
两个入口答案不一致先别调模型:6 行入口口径对账表(附脚本)
人工智能·后端·python·大语言模型·1024程序员节
thefool1122667 小时前
TCP 1
java·1024程序员节
码事漫谈8 小时前
消除AI幻觉,普通人能做的五件事
后端
金銀銅鐵10 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
AI人工智能+电脑小能手10 小时前
一次请求打几个下游,这个Java并行任务工具类6个方法按序聚合
java·线程池·并发编程·1024程序员节·批量处理·并行任务
Mk5987811 小时前
给 Agent 装上对话框 —— AgentScope-Java 接入 Spring Boot 与 SSE 流式实战
后端
付威202311 小时前
从 Loop 到 Runtime:rpi Agent Loop 与 Cordis 的边界、取舍与组合
后端