Properties.load() 读不到 classpath 文件因误用 FileInputStream,应改用 getClass().getClassLoader().getResourceAsStream();load() 解析 key=value 文本(默认 ISO-8859-1),loadFromXML() 专用于 XML 格式;Spring Boot 中应避免手动 new Properties,优先用 @ConfigurationProperties;Properties 单操作线程安全但复合操作不安全,高并发建议用 ConcurrentHashMap。

Properties.load() 为什么读不到 classpath 下的配置文件
常见现象是 FileNotFoundException,尤其当用 new FileInputStream("config.properties") 直接构造时——这会从当前工作目录(如 IDEA 的 project root)找文件,而非 classpath。正确做法是走类加载器路径:
- 用
getClass().getClassLoader().getResourceAsStream("config.properties"),确保从 classpath 根开始查找 - 若配置在子包(如
conf/app.properties),路径要写全:"conf/app.properties" - 注意返回值可能为
null,务必判空,否则触发NullPointerException
Properties.load() 和 loadFromXML() 的实际区别在哪
二者语法和用途完全不同,不能混用:
-
load()解析 key=value 形式的纯文本,支持#或!开头的注释,但不校验编码,默认按 ISO-8859-1 读取;中文需提前用native2ascii转义或改用load(new InputStreamReader(in, "UTF-8")) -
loadFromXML()只接受标准 XML 格式(),天然支持 UTF-8,无需转义,但写起来麻烦,且不兼容传统 .properties 文件b - 别对 XML 文件调
load(),会抛InvalidPropertiesFormatException
Spring Boot 里还该手动 new Properties 吗
在 Spring Boot 环境中,直接 new Properties 并手动 load 属于重复造轮子,容易绕过自动配置机制:
- 应用级配置应走
@ConfigurationProperties或@Value,由 Spring 管理生命周期和类型转换 - 若必须读取外部非 standard 配置(如 legacy .properties),优先用
ResourceLoader.getResource("classpath:xxx.properties")获取InputStream,再喂给Properties.load() - 避免在 @Component 初始化块里硬编码路径,会导致测试难 mock、Profile 切换失效
Properties 是线程安全的吗?并发修改会出什么问题
Properties 继承自 Hashtable,其 get()、put() 方法是 synchronized 的,但仅限单个操作原子性:
立即学习“Java免费学习笔记(深入)”;
- 复合操作(如先
get()再put())不保证原子,仍需外部同步 - 遍历过程中被修改会触发
ConcurrentModificationException,因内部 modCount 检查未被屏蔽 - 高并发场景下性能差,建议用
ConcurrentHashMap替代,配合Files.readAllLines()+ 手动解析,更可控
load(),报错信息又不细看,就去网上搜“Properties 读取失败”,其实错误类型已经指明了问题。










