使 Java 属性跨类可用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4750131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Make Java Properties available across classes?
提问by tzippy
I chose to take properties file for customization of some settings. I use the following code to make a Properties Object available in a class
我选择使用属性文件来自定义一些设置。我使用以下代码使属性对象在类中可用
Properties defaultProps = new Properties();
try {
FileInputStream in = new FileInputStream("custom.properties");
defaultProps.load(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
Do I have to add this to every class? Probably not because then every class would open a stream to this file.
But I'm not sure how to handle this properly.
Should I make a class MyProperties
and instantiate it in whatever class needs properties?
我是否必须将其添加到每个班级?可能不是因为这样每个类都会打开一个指向这个文件的流。但我不确定如何正确处理这个问题。我应该创建一个类MyProperties
并在任何需要属性的类中实例化它吗?
Thanks in advance!
提前致谢!
回答by Péter T?r?k
Once you initialized defaultProps
, you can make its contents available to other objects in your app e.g. via a public static accessor method, e.g.:
初始化后defaultProps
,您可以将其内容提供给应用程序中的其他对象,例如通过公共静态访问器方法,例如:
public class Config {
private static Properties defaultProps = new Properties();
static {
try {
FileInputStream in = new FileInputStream("custom.properties");
defaultProps.load(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getProperty(String key) {
return defaultProps.getProperty(key);
}
}
This is the simplest approach, however it creates an extra dependency which makes unit testing harder (unless you provide a method in Config
to set a mock property object for unit testing).
这是最简单的方法,但是它创建了一个额外的依赖项,这使得单元测试更加困难(除非您提供了一个方法Config
来设置单元测试的模拟属性对象)。
An alternative is to inject defaultProps
(or individual configuration values from it) into each object which needs it. However, this may mean you need to add extra parameter(s) to lots of methods if your call hierarchies are deep.
另一种方法是将defaultProps
(或来自它的单个配置值)注入到需要它的每个对象中。但是,如果您的调用层次结构很深,这可能意味着您需要向许多方法添加额外的参数。
回答by SirDarius
If you only need one instance of your properties class you can use the singleton (anti?)-pattern.
如果你只需要你的属性类的一个实例,你可以使用单例(反?)模式。
It would look like a class like this:
它看起来像这样一个类:
public class MyProperties extends Properties {
private static MyProperties instance = null;
private MyProperties() {
}
public static MyProperties getInstance() {
if (instance == null) {
try {
instance = new MyProperties();
FileInputStream in = new FileInputStream("custom.properties");
instance.load(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
return instance;
}
}
回答by fmucar
Why not use a static ResourceBundle ?
为什么不使用静态 ResourceBundle ?
static final ResourceBundle myResources =
ResourceBundle.getBundle("MyResources", currentLocale);
回答by Nilesh
Rather than loading properties in every class. Load it somewhere around main() and pass it to other classes via their constructors.
而不是在每个类中加载属性。将它加载到 main() 周围的某个地方,并通过它们的构造函数将它传递给其他类。
Don't share them globally. - Difficult to test - Against the abstraction (Global access, DAO can access user settings. it should be prevented by passing only what it needs.. not everything) - Classes lie what they need
不要在全球范围内共享它们。- 难以测试 - 反对抽象(全局访问,DAO 可以访问用户设置。应该通过只传递它需要的东西来阻止它......不是所有的东西) - 类就是他们需要的东西
回答by Courtney Christensen
Since this information is static across all instances, I recommend implementing the Properties
class as a singleton. By using the static
initialization blockmethod, you can have it load the file automatically when the program starts up.
由于此信息在所有实例中都是静态的,因此我建议将该Properties
类实现为单例。通过使用static
初始化块方法,您可以让它在程序启动时自动加载文件。
public class Properties {
static {
try {
FileInputStream in = new FileInputStream("custom.properties");
load(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
protected static void load(FileInputStream in) {
// existing load functionality here
}
}
You are still going to need an internal storage mechanism and accessor mechanism. These should also be marked static
.
您仍然需要一个内部存储机制和访问器机制。这些也应该被标记static
。
回答by Kent Murra
There's too little information to determine what the best way to handle this would be. You may want to expose it using an accessor, or pass it into each class that requires it. Alternatively, you may pull out the properties that each class needs and pass their values into the class's constructor.
信息太少,无法确定处理此问题的最佳方法是什么。您可能希望使用访问器公开它,或将其传递给需要它的每个类。或者,您可以提取每个类需要的属性并将它们的值传递给类的构造函数。
回答by jzd
Load the properties once using and store the Properties somewheres that others classes can pull from. If that is a MyProperties class that references a static variable somewhere that is fine.
使用一次加载属性并将属性存储在其他类可以从中提取的地方。如果这是一个在某处引用静态变量的 MyProperties 类,那很好。
回答by maaartinus
This is a special case of making anything available globally. Using static methods is quite bad. A better but bad solution is using the sigletonpattern. Testing is the greatest problem here. IMHO, the best way is using Dependency injection, although it may be an overkill for small applications.
这是在全球范围内提供任何东西的特殊情况。使用静态方法非常糟糕。一个更好但不好的解决方案是使用单例模式。测试是这里最大的问题。恕我直言,最好的方法是使用Dependency injection,尽管它对于小型应用程序来说可能是一种矫枉过正。