You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何读取Properties文件中重复键的最后一个对应值?

嘿,我懂你现在的困扰——合并后的mail.properties里有重复的键,而ResourceBundle默认只会取第一个出现的值,但你需要的是最后那条对应的内容对吧?别担心,这里有两个实用的方案帮你解决:

方案1:直接使用java.util.Properties加载(推荐)

Properties类的load()方法天生就支持后面的键值对覆盖前面的,完全符合你的需求,而且实现起来最简单:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class LoadLastPropertyValue {
    public static void main(String[] args) {
        Properties mailProps = new Properties();
        try (InputStream inputStream = new FileInputStream("path/to/your/mail.properties")) {
            // 加载文件时自动用最后出现的键值覆盖之前的
            mailProps.load(inputStream);
            
            // 获取最终的对应值
            String finalMailBody = mailProps.getProperty("mail.body"); // 得到 "body3"
            String finalMailSubject = mailProps.getProperty("mail.subject"); // 得到 "Reminder"
            
            System.out.println("最终邮件正文:" + finalMailBody);
            System.out.println("最终邮件主题:" + finalMailSubject);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
方案2:自定义ResourceBundle.Control(如果必须用ResourceBundle)

如果你的项目架构必须依赖ResourceBundle,可以自定义一个Control类,内部用Properties处理重复键,再包装成ResourceBundle返回:

首先定义自定义Control:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.ResourceBundle;

public class LastValueResourceBundleControl extends ResourceBundle.Control {
    @Override
    public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
            throws IllegalAccessException, InstantiationException, IOException {
        String bundleName = toBundleName(baseName, locale);
        String resourceName = toResourceName(bundleName, "properties");
        
        try (InputStream inputStream = loader.getResourceAsStream(resourceName)) {
            if (inputStream != null) {
                Properties props = new Properties();
                props.load(inputStream); // 用Properties处理重复键,自动覆盖
                // 将处理后的Properties转为PropertyResourceBundle
                return new PropertyResourceBundle(new ByteArrayInputStream(props.toString().getBytes()));
            }
        }
        // fallback到默认实现
        return super.newBundle(baseName, locale, format, loader, reload);
    }
}

然后使用这个Control加载ResourceBundle:

import java.util.Locale;
import java.util.ResourceBundle;

public class ResourceBundleDemo {
    public static void main(String[] args) {
        ResourceBundle mailBundle = ResourceBundle.getBundle("mail", Locale.getDefault(), new LastValueResourceBundleControl());
        
        String finalMailBody = mailBundle.getString("mail.body"); // "body3"
        String finalMailSubject = mailBundle.getString("mail.subject"); // "Reminder"
        
        System.out.println("最终邮件正文:" + finalMailBody);
        System.out.println("最终邮件主题:" + finalMailSubject);
    }
}

补充说明

为什么ResourceBundle默认不行?因为它的默认实现在读取properties文件时,遇到重复键会直接忽略后续的条目,只保留第一个出现的值;而Properties类则正好相反,会用后续的新值覆盖旧值,这也是我们能利用它解决问题的核心原因。

内容的提问来源于stack exchange,提问作者ecdhe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:20:29