下面我将为你详细介绍几种主流的读取方法,从最传统到最现代,并附上完整的代码示例和最佳实践。

准备工作:创建一个 config.properties 文件
在你的项目根目录(通常是 src/main/resources)下创建一个名为 config.properties 的文件,内容如下:
# Database Configuration db.url=jdbc:mysql://localhost:3306/mydb db.username=admin db.password=secret # Application Settings app.name=MyCoolApp app.version=1.0.0 debug.mode=true
使用 java.util.Properties 类(最传统、最核心)
这是最基础也是最核心的方法,适用于所有 Java 版本,它通过 ClassLoader 来加载资源文件,可以很好地处理路径问题。
核心步骤:
- 创建
Properties对象。 - 使用
ClassLoader获取资源文件的输入流InputStream。 - 调用
properties.load(inputStream)加载文件内容。 - 通过
properties.getProperty("key")获取属性值。 - 务必关闭输入流(推荐使用
try-with-resources语句)。
代码示例:
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesFileReader {
public static void main(String[] args) {
// 1. 创建 Properties 对象
Properties properties = new Properties();
// try-with-resources 语句会自动关闭 InputStream
try (InputStream input = PropertiesFileReader.class.getClassLoader().getResourceAsStream("config.properties")) {
// 2. 检查文件是否存在
if (input == null) {
System.out.println("Sorry, unable to find config.properties");
return;
}
// 3. 加载属性文件
properties.load(input);
// 4. 获取属性值
String dbUrl = properties.getProperty("db.url");
String dbUsername = properties.getProperty("db.username");
String dbPassword = properties.getProperty("db.password");
String appName = properties.getProperty("app.name");
String appVersion = properties.getProperty("app.version");
String debugMode = properties.getProperty("debug.mode");
// 5. 打印结果
System.out.println("Database URL: " + dbUrl);
System.out.println("Database Username: " + dbUsername);
System.out.println("Database Password: " + dbPassword);
System.out.println("App Name: " + appName);
System.out.println("App Version: " + appVersion);
System.out.println("Debug Mode: " + debugMode);
// 获取不存在的 key,可以提供默认值
String timeout = properties.getProperty("request.timeout", "30");
System.out.println("Request Timeout (default if not set): " + timeout);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
关键点说明:
getClassLoader().getResourceAsStream("config.properties"): 这是推荐的方式,它会从CLASSPATH(即src/main/resources目录)中查找文件,文件名前不需要斜杠 。- 如果文件路径是绝对路径(不推荐,因为会破坏可移植性),可以使用
new FileInputStream("C:/path/to/config.properties")。 getProperty(String key): key 不存在,返回null。getProperty(String key, String defaultValue): key 不存在,返回指定的默认值,非常实用。
使用 java.util.ResourceBundle 类(国际化场景专用)
ResourceBundle 专门用于国际化(i18n),但它也可以用来读取普通的 .properties 文件,它的优点是性能更好(缓存机制),并且支持不同语言环境的文件(如 config_en_US.properties)。

核心步骤:
- 不需要创建
ResourceBundle实例,直接使用静态方法getBundle()。 - 文件名不需要扩展名。
- 通过
resourceBundle.getString("key")获取值。
代码示例:
import java.util.ResourceBundle;
public class ResourceBundleReader {
public static void main(String[] args) {
// 1. 获取 ResourceBundle 对象
// 文件名是 "config",不需要 .properties 后缀
// 它会自动从 CLASSPATH 中查找
ResourceBundle resourceBundle = ResourceBundle.getBundle("config");
// 2. 获取属性值
String dbUrl = resourceBundle.getString("db.url");
String appName = resourceBundle.getString("app.name");
String debugMode = resourceBundle.getString("debug.mode");
// 3. 打印结果
System.out.println("App Name (from ResourceBundle): " + appName);
System.out.println("Database URL (from ResourceBundle): " + dbUrl);
System.out.println("Debug Mode (from ResourceBundle): " + debugMode);
// key 不存在,会抛出 MissingResourceException
// String timeout = resourceBundle.getString("request.timeout"); // 这行会报错
}
}
关键点说明:
- 性能:
ResourceBundle会被缓存,多次调用getBundle("config")会返回同一个实例,性能优于每次都重新读取文件。 - 局限性:
ResourceBundle主要用于处理字符串资源,它无法直接加载非.properties格式的文件(如 XML),key 不存在,会抛出MissingResourceException,而不是返回null。 - 命名约定:对于多语言,文件名遵循
基名_语言代码_国家代码.properties的格式,如config_zh_CN.properties。getBundle("config")会根据 JVM 的默认 Locale 自动选择最合适的文件。
使用 Spring Boot 的 @ConfigurationProperties(现代 Spring 项目首选)
如果你正在使用 Spring Boot,这是最推荐、最优雅、类型最安全的方式,它可以将配置文件中的属性直接绑定到一个 Java 对象(POJO)中,避免了大量的 getProperty() 调用和类型转换。
核心步骤:
- 创建一个与配置结构匹配的 Java 类(POJO)。
- 在类上使用
@ConfigurationProperties注解,并指定前缀。 - 在 Spring Boot 的主配置类(
@SpringBootApplication)或配置类上使用@EnableConfigurationProperties启用该功能。 - 通过依赖注入(
@Autowired)使用这个配置对象。
代码示例:
创建配置类 AppConfig.java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component // 将其声明为 Spring Bean
@ConfigurationProperties(prefix = "db") // 指定属性前缀
public class DatabaseConfig {
private String url;
private String username;
private String password;
// 必须提供 getter 和 setter 方法
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "DatabaseConfig{" +
"url='" + url + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
在主应用类中启用

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties(AppConfig.class) // 启用自定义配置类
public class MyApplication implements CommandLineRunner {
@Autowired
private AppConfig appConfig; // 自动注入配置对象
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// 直接使用注入的配置对象,非常方便
System.out.println("--- Using Spring Boot @ConfigurationProperties ---");
System.out.println("App Name: " + appConfig.getDbUrl()); // 注意,这里访问的是 url
System.out.println("App Version: " + appConfig.getDbUsername()); // 注意,这里访问的是 username
System.out.println("Debug Mode: " + appConfig.getDbPassword()); // 注意,这里访问的是 password
}
}
关键点说明:
- 类型安全:
@ConfigurationProperties会自动进行类型转换(如"true"会转换为boolean类型)。 - 松绑定:属性名与字段名的匹配是宽松的,支持驼峰命名(
camelCase)、短横线(kebab-case或my-config)和下划线(snake_case或my_config)。 - 元数据支持:在 IDE(如 IntelliJ IDEA)中,当你使用
@ConfigurationProperties时,可以获得自动补全和配置提示,非常友好。 - 推荐做法:通常将不同模块的配置放在不同的文件中(如
application-db.properties),然后使用@PropertySource或@ConfigurationProperties的location属性来指定。
总结与对比
| 特性 | java.util.Properties |
java.util.ResourceBundle |
Spring @ConfigurationProperties |
|---|---|---|---|
| 适用场景 | 任何 Java 项目,核心基础 | 国际化(i18n),简单读取 | 现代 Spring/Spring Boot 项目 |
| 依赖 | 无 | 无 | 需要 Spring/Spring Boot 框架 |
| 类型安全 | ❌ (手动 String 转换) |
❌ (仅支持 String) |
✅ (自动类型转换) |
| 易用性 | 中等 (需手动处理流和异常) | 较好 (但会抛异常) | 极佳 (对象化访问) |
| 性能 | 每次读取文件 | 高 (缓存机制) | 高 (启动时加载) |
| IDE 支持 | 一般 | 一般 | 优秀 (自动补全、提示) |
| 推荐指数 | ⭐⭐⭐⭐ (通用性最强) | ⭐⭐⭐ (特定场景) | ⭐⭐⭐⭐⭐ (Spring 项目首选) |
最佳实践建议
- 纯 Java 项目:使用
java.util.Properties和ClassLoader是最稳妥、最通用的选择。 - 需要国际化:使用
java.util.ResourceBundle。 - Spring / Spring Boot 项目:毫不犹豫地使用
@ConfigurationProperties,它能让你写出更干净、更易于维护、更不易出错的代码,这是现代 Java 开发的标准实践。
