实体类字段用 @Value 赋了默认值,取出来还是 null?

测试环境导数据,一万两千单跑到八千多行挂了。 日志里有用的一行:

复制代码
java.lang.NullPointerException

底下 at 那几行是业务包名,我不贴。 指过去的代码是这句:

java 复制代码
`String path = tmpPath + "/upload";
`

tmpPath 上面明明挂着注解:

java 复制代码
`@Value("${file.tmp.path}")
private String tmpPath;
`

我第一反应是配置漏了。 可同一个 key 在 application.yml 里躺着,测试环境那份也有, 本地单测还是绿的。

卡了半小时才看到调用方那一句:

java 复制代码
`ExcelHelper helper = new ExcelHelper();
`

就这。 我一直以为 @Value 是编译期就把值写进字段的那种注解。 实际是容器创建 bean 之后,再回头把值塞进字段。 自己 new 的对象容器根本不认识,它插不上手, 字段就停在 Java 给的初始值那一步,引用类型是 null。

我本地单测能过,是因为拿的是容器里的实例:

java 复制代码
`@Autowired
private ExcelHelper helper;
`

同一个类,两种拿法,一个有值一个没值。 Spring Boot 2.1.6,跟版本没关系,纯粹是拿对象的方式不对。

另外两种写法也常被一起提,我得分开说。

字段是 static 的,我能确定的只有一件事: 这个类压根没进容器的时候,它跟实例字段一样没人管,一直 null。 容器管的 bean 能不能把值写进静态字段我没试过, 网上那种「static 一律注不进去」的绝对话我也不太敢信。

final 那个我原本以为也是同一个坑,其实不成立。 不给初值、构造里也不赋值,它根本跑不起来,javac 先拦一道:

复制代码
FinalBlank.java:2: error: variable tmpPath not initialized
in the default constructor

编译都过不去,拿不到 null,这一种不用防。

还有一个误会挺多的:${key} 里得加冒号才算给默认值。

java 复制代码
`@Value("${file.tmp.path:}")
@Value("${file.tmp.path:/data}")
`

冒号后面留空也算给了,给的是空串。

冒号都不写、配置又真缺了,那反而好查,启动阶段直接给你:

复制代码
Could not resolve placeholder 'file.tmp.path'

进程起不来,不会拖到跑数据跑到一半。 最怕的是压根没进容器这种,一声不吭。

我原本想加一行日志自查,看类名是不是带 CGLIB 那一长串后缀。 后来发现这条路不成立:这个类身上没有任何 AOP, 容器给的实例类名也是光秃秃的,跟 new 出来的长得一样。

改成看这行日志打几次:

java 复制代码
`public ExcelHelper() {
    log.info("ExcelHelper init");
}
`

容器里是单例,整个进程就一行。 谁在 new 它,调一次刷一行,一眼就能看出来。

数据我后来重导了一遍,八千行往后那部分补上的。 tmpPath 这个坑算是填了,可测试环境那边改一次路径就得重启一次服务, 每次七八分钟起不来,这事一直挂着没人管。

相关推荐
破芽27 分钟前
learn-claude-code-s05-s11-学习笔记
笔记·学习
程序猿乐锅2 小时前
【从0-1学习Python | 第七篇】Python 面向对象基础
开发语言·笔记·后端·python·学习·1024程序员节
fish_zzzz2 小时前
笔记--浅谈内存,存储空间,BIOS芯片,显卡GPU、VRAM(1)
笔记·1024程序员节
ACP广源盛139246256732 小时前
PCIe Gen3 交换芯片选型笔记:多路扩展方案 IX7024@ACP 评估
笔记·硬件架构·pcie·国产芯片
深圳老胡2 小时前
STM32 开发中 Trae 内置模型怎么选:Seed、MiniMax、GLM、DeepSeek、Kimi、Qwen 全对比
笔记·stm32·单片机·嵌入式硬件·代码规范·1024程序员节
坤坤子吖3 小时前
C++继承:友元、静态成员、多继承与组合
开发语言·c++·笔记·学习·1024程序员节
Nuanyt4 小时前
Hot 100 刷题笔记 · 数组与哈希专题(3 题)
java·笔记·算法·leetcode·哈希算法·1024程序员节
速德瑞仪器4 小时前
如何精准把控紫外能量,选择合适的UV能量计
经验分享·紫外辐照计
lazy H4 小时前
【计算机网络】第 5 篇:TCP 和 UDP 有什么区别?从 Java 后端场景理解两种传输协议
经验分享·后端·网络协议·tcp/ip·计算机网络·1024程序员节
破芽5 小时前
learn-claude-code-s08-s09-学习笔记
笔记·学习