Properties.load()路径错误会抛FileNotFoundException,应使用类路径加载并判空;中文乱码因默认ISO-8859-1解码,JDK9+用load(Reader)指定UTF-8,JDK8需InputStreamReader转码;获取属性须用带默认值重载并封装类型转换;Properties无嵌套、多环境、热更新支持,复杂场景应选@ConfigurationProperties等替代方案。

Properties.load() 读取配置文件时路径不对会报 FileNotFoundException
Java 的 Properties 类本身不负责定位文件,只负责解析键值对。所以 load(InputStream) 传入的流如果来源路径错误,就会直接抛出 FileNotFoundException 或 NullPointerException(比如传了 null 流)。
常见误区是用 new FileInputStream("config.properties") 写相对路径——这依赖当前工作目录(user.dir),而 IDE、Maven、Docker 启动时该目录往往不是你预期的位置。
- 推荐用类路径加载:
getClass().getResourceAsStream("/config.properties")(注意开头斜杠表示从 classpath 根开始) - 若配置在
src/main/resources/conf/app.properties,则路径写/conf/app.properties - 用
Thread.currentThread().getContextClassLoader().getResourceAsStream(...)更稳妥,尤其在容器或框架中 - 别忘了判空:
if (input == null) throw new IllegalArgumentException("config.properties not found in classpath");
中文乱码问题大多出在 load() 没指定字符集
Properties.load(InputStream) 默认按 ISO-8859-1 解码,遇到 UTF-8 编码且含中文的配置文件,就会显示为乱码(如 \u4F60\u597D 是正常转义,但直接显示问号或方块就说明解码失败)。
- JDK 9+ 可用
load(Reader)配合InputStreamReader显式指定编码:props.load(new InputStreamReader(input, StandardCharsets.UTF_8)) - JDK 8 及以下没有
load(Reader)重载,必须先用InputStreamReader转码再调load(),否则只能把中文写成 Unicode 转义形式(key=\u4F60\u597D) - 验证方式:打印
props.getProperty("key")看是否为预期中文,而不是一串\u序列或乱码字符
用 getProperty(key, defaultValue) 避免 NullPointerException
直接调 getProperty("timeout") 在 key 不存在时返回 null,后续若直接用于 Integer.parseInt() 就崩了。这不是配置读取失败,而是使用姿势问题。
立即学习“Java免费学习笔记(深入)”;
- 始终优先用带默认值的重载:
props.getProperty("timeout", "3000") - 数值类型建议封装工具方法,例如:
getInt(props, "timeout", 3000),内部做非空判断和异常捕获 - 注意默认值只是字符串,
getProperty("flag", "true")返回的是字符串"true",不是布尔值,需自行Boolean.parseBoolean()
Properties 不支持嵌套、数组或注释折叠,复杂配置建议换方案
Properties 本质是 Hashtable,所有值都是字符串,没有类型、层级或结构概念。像 db.urls=url1,url2,url3 或 cache.enabled=true 看似简单,但一旦需要校验、分组、动态刷新,就会很快失控。
- 多环境配置?Properties 无法原生区分
dev/prod,得靠不同文件名 + 手动切换 - 需要热更新?
Properties本身无监听机制,每次 reload 都要新建实例、重新 load 流,且无法原子替换 - 替代选择:Spring Boot 的
@ConfigurationProperties、Apache Commons Configuration 2、或者直接上 YAML + SnakeYAML
除非项目极小、配置极少、且确定永不扩展,否则别硬扛着用 Properties 做唯一配置载体。它适合“启动参数级”的扁平键值,不适合“系统配置级”的语义化管理。










