Java中的常量和属性

12

Java最佳实践建议将属性作为常量进行读取。那么,您认为最好的方法是什么?我的做法是:创建一个配置类以仅一次读取属性文件(单例模式),并使用此类在需要时作为常量读取属性。还有一个常量类用于存储:

  • 属性名称以在属性文件中找到它们(例如app.database.url)。
  • 静态常量(我不希望用户对其进行配置的那些,例如CONSTANT_URL="myurl.com")。
public final class Configurations {

private Properties properties = null;
private static Configurations instance = null;

/** Private constructor */
private Configurations (){
    this.properties = new Properties();
    try{
        properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(Constants.PATH_CONFFILE));
    }catch(Exception ex){
        ex.printStackTrace();
    }
}   

/** Creates the instance is synchronized to avoid multithreads problems */
private synchronized static void createInstance () {
    if (instance == null) { 
        instance = new Configurations ();
    }
}

/** Get the properties instance. Uses singleton pattern */
public static Configurations getInstance(){
    // Uses singleton pattern to guarantee the creation of only one instance
    if(instance == null) {
        createInstance();
    }
    return instance;
}

/** Get a property of the property file */
public String getProperty(String key){
    String result = null;
    if(key !=null && !key.trim().isEmpty()){
        result = this.properties.getProperty(key);
    }
    return result;
}

/** Override the clone method to ensure the "unique instance" requeriment of this class */
public Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException();
}}

Constant类包含对属性和常量的引用。

public class Constants {
// Properties (user configurable)
public static final String DB_URL = "db.url";
public static final String DB_DRIVER = "db.driver";

// Constants (not user configurable)
public static final String PATH_CONFFILE = "config/config.properties";
public static final int MYCONSTANT_ONE = 1;
}

属性文件将是:

db.url=www.myurl.com
db.driver=mysql

阅读属性和常量应该是:

// Constants
int i = Constants.MYCONSTANT_ONE;
// Properties
String url = Configurations.getInstance().getProperty(Constants.DB_URL);

你认为这是一个好的方法吗?你在Java中读取属性和常量的方式是什么?

提前致谢。

2个回答

8
我找到了一种更好的解决方案,可以将代码同化并将所有内容作为常量。使用相同的配置类和.properties文件:由于getInstance()方法是静态的,因此可以在Constants类中初始化常量。
一个用于存储.properties文件中属性名称的类:
public class Properties {
// Properties (user configurable)
public static final String DB_URL = "db.url";
public static final String DB_DRIVER = "db.driver";
}

然后,Constant类将会是:

public class Constants {
// Properties (user configurable)
public static final String DB_URL = Configurations.getInstance().getProperty(Properties.DB_URL);
public static final String DB_DRIVER = Configurations.getInstance().getProperty(Properties.DB_DRIVER );

// Constants (not user configurable)
public static final String PATH_CONFFILE = "config/config.properties";
public static final int MYCONSTANT_ONE = 1;
}

最后,使用它们的方法如下:

// Constants
int i = Constants.MYCONSTANT_ONE;
// Properties
String url = Constants.DB_URL;

我认为这是一个干净而优雅的解决方案,可以解决测试中的常量和属性问题。


2
正如Fabien所评论的那样,也可以将getProperty功能放入getInstance中,并将其重命名为新的getProperty,以避免调用getInstance().getProperty,但我在帖子中保留了这种方式,因为这样更容易理解。 - Esteban S

2
我认为你应该看一下 Apache Commons Configuration,你会发现它非常有用。你可以做很多事情,比如为你的配置文件设置层级结构,指定多个来源。
对于 Constants ,它看起来不错 :)

2
不客气。我提出了这个解决方案,因为我知道我们有时需要一个可以从不同支持中获取属性的解决方案。否则你采用的解决方案也很好。我只是会将 getProperty 设置为静态并将 getInstance 包含在其中,以避免需要检索属性的方法中调用 getInstance - Fabien
1
感谢您的回复,这是一个强大的JNDI或XML库,但在我看来,对于简单的属性文件,使用java.util的简单性更可取。此外,可以通过添加多个源来加载新资源,并使用Properties.putAll方法将其添加到java.util.Properties实现Map中。 - Esteban S

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接