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

Java中如何从.yaml文件加载配置到类?使用SnakeYaml遇报错

问题:SnakeYAML加载YAML配置报错

使用SnakeYAML库加载.yaml配置文件时,抛出NoSuchMethodException: com.example.Settings$Database.<init>()错误。

我的Settings类代码

package com.example;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import org.yaml.snakeyaml.Yaml;

public class Settings {
    private final static InputStream file;
    private final static Settings parsedSettings;
    public Database database;
    static {
        try {
            file = new FileInputStream("./src/main/java/com/example/settings.yaml");
            Yaml yaml = new Yaml();
            parsedSettings = yaml.loadAs(file, Settings.class);
        } catch(FileNotFoundException ex) {
            ex.printStackTrace();
            throw new RuntimeException("Settings file not found or cannot be readed");
        }
    }
    public Settings(){
        this.database = parsedSettings.database;
    }

    public class Database {
        private String driver;
        private String user;
        private String password;
        private String host;
        private int    port;
        private String name;

        private Database(String driver, String user, String password, String host, int port, String name){
            this.driver   = driver;
            this.user     = user;
            this.password = password;
            this.host     = host;
            this.port     = port;
            this.name     = name;
        }

        public String getDriver() {
            return this.driver;
        }
        public String getUser() {
            return this.user;
        }
        public String getPassword() {
            return this.password;
        }
        public String getHost() {
            return this.host;
        }
        public int getPort() {
            return this.port;
        }
        public String getDatabaseName() {
            return this.name;
        }
    }
}

我的settings.yaml配置

database:
  driver: mysql
  user: root
  password:
  host: localhost
  port: 3306
  name: java_messages_app

目前未使用任何框架,仅依赖第三方库,不确定该用静态方式还是构造方法加载配置,请求解决问题。


解决方案

1. 修复内部类核心问题

报错的根本原因有两个:

  • Database是非静态内部类,SnakeYAML无法直接实例化(非静态内部类依赖外部类实例)
  • Database仅提供带参构造,SnakeYAML反射实例化对象时需要无参构造

修改后的Database类:

public static class Database {
    private String driver;
    private String user;
    private String password;
    private String host;
    private int    port;
    private String name;

    // 添加无参构造方法
    public Database() {}

    private Database(String driver, String user, String password, String host, int port, String name){
        this.driver   = driver;
        this.user     = user;
        this.password = password;
        this.host     = host;
        this.port     = port;
        this.name     = name;
    }

    // 原有getter方法保留
    public String getDriver() { return this.driver; }
    public String getUser() { return this.user; }
    public String getPassword() { return this.password; }
    public String getHost() { return this.host; }
    public int getPort() { return this.port; }
    public String getDatabaseName() { return this.name; }
}

2. 优化配置加载逻辑

原静态代码块存在资源泄漏(InputStream未关闭)、类加载异常风险高的问题,建议改成懒加载单例模式,保证配置仅加载一次且资源处理更安全:

package com.example;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.yaml.snakeyaml.Yaml;

public class Settings {
    private static Settings instance;
    public Database database;

    // 私有构造,禁止外部直接实例化
    private Settings() {}

    // 线程安全的懒加载获取实例
    public static synchronized Settings getInstance() {
        if (instance == null) {
            // 使用try-with-resources自动关闭流
            try (InputStream file = new FileInputStream("./src/main/java/com/example/settings.yaml")) {
                Yaml yaml = new Yaml();
                instance = yaml.loadAs(file, Settings.class);
            } catch (FileNotFoundException ex) {
                ex.printStackTrace();
                throw new RuntimeException("Settings file not found or cannot be read");
            } catch (IOException ex) {
                ex.printStackTrace();
                throw new RuntimeException("Failed to read settings file");
            }
        }
        return instance;
    }

    public static class Database {
        private String driver;
        private String user;
        private String password;
        private String host;
        private int port;
        private String name;

        public Database() {}

        // getter方法保留
        public String getDriver() { return driver; }
        public String getUser() { return user; }
        public String getPassword() { return password; }
        public String getHost() { return host; }
        public int getPort() { return port; }
        public String getDatabaseName() { return name; }
    }
}

3. 使用方式

后续在代码中通过单例方法获取配置实例:

Settings settings = Settings.getInstance();
System.out.println(settings.database.getDatabaseName()); // 输出java_messages_app

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:05:00