Java - 创建包范围或全局变量的最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24350683/
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
Java - best practice for creating package-wide or global variables
提问by Alium Britt
What is the standard approach/best practice to creating variables that are program- or package-wide in Java?
在 Java 中创建程序或包范围的变量的标准方法/最佳实践是什么?
I want to set up some global variables that are accessible by multiple classes. Examples of these global variables would be things like a boolean flag testModeOn, a language setting, current local server, time display format, etc. According to some other questions (namely this one) there aren't any global variables, but there are some work-arounds using interfaces (not recommended?) or classes. Since the original poster didn't explain their situation, they got nearly every answer under the sun and I want to ask specifically for program configuration variables.
我想设置一些可由多个类访问的全局变量。这些全局变量的示例包括布尔标志 testModeOn、语言设置、当前本地服务器、时间显示格式等。根据其他一些问题(即this),没有任何全局变量,但有一些使用接口(不推荐?)或类的解决方法。由于原发帖者没有说明他们的情况,他们几乎得到了所有答案,我想专门询问程序配置变量。
Is it better to create a class/package/interface and then import it into my working class/package? Is there anything I should be aware of when trying to implement these variables using a separate class or interface? Is there any other way to fudge package-level variables since Java apparently doesn't do this natively?
创建一个类/包/接口然后将其导入我的工作类/包是否更好?在尝试使用单独的类或接口实现这些变量时,有什么我应该注意的吗?有没有其他方法来捏造包级变量,因为 Java 显然不是本机这样做的?
NOTE: These variables would probably not change except when the program is re-compiled.
注意:除非重新编译程序,否则这些变量可能不会更改。
采纳答案by Bobulous
If you're talking about constants, then they should be declared as static final
fields in a class (never in an interface, according to Joshua Bloch).
如果你在谈论常量,那么它们应该被声明为static final
类中的字段(根据 Joshua Bloch 的说法,永远不要在接口中)。
If you're talking about settings which can change on the fly, then these could be either static
fields in a class, or you could create a ConfigHandler class to manage the setting and fetching of configurable values.
如果您谈论的是可以动态更改的设置,那么这些设置可以是static
类中的字段,也可以创建一个 ConfigHandler 类来管理设置和获取可配置值。
Using class fields for mutable values might lead to concurrency problems, so if your application is multi-threaded it might be better to create a ConfigHandler class which manages concurrent access carefully and provides synchronized
methods to avoid problems.
将类字段用于可变值可能会导致并发问题,因此如果您的应用程序是多线程的,最好创建一个 ConfigHandler 类,该类仔细管理并发访问并提供synchronized
避免问题的方法。
回答by robinrjoe
Create a Bean class if multiple variables are required to be used in different classes. Best practice is to create a private variable with its getters and setters.
如果需要在不同的类中使用多个变量,则创建一个 Bean 类。最佳实践是创建一个带有 getter 和 setter 的私有变量。
public class ListBean implements Serializable
{
private boolean testModeOn;
public boolean getTestModeOn()
{
return testModeOn;
}
public setTestModeOn(boolean testModeOn)
{
this.testModeOn = testModeOn;
}
回答by Zarathustra
In general there are so many ways to do it wrong regarding this topic.
一般来说,关于这个话题有很多方法可以做错。
The simple way is to use a Singelton. This is not an option - Singelton is an Anti-Pattern. http://c2.com/cgi/wiki?SingletonsAreEvil
简单的方法是使用 Singelton。这不是一个选项 - Singelton 是一种反模式。http://c2.com/cgi/wiki?SingletonAreEvil
So what is else there? An Interface with public static final
variables?
Not an option - Thats simply not the use case of an interface: https://stackoverflow.com/a/2659740/1248724
那么还有什么呢?带public static final
变量的接口?不是一个选项 - 这根本不是接口的用例:https: //stackoverflow.com/a/2659740/1248724
so what is else there? The answer is:
那么还有什么呢?答案是:
What I prefer is the spring boot way (e.g. Dependency Injection) Here an code example which is obviously Spring.
我更喜欢的是 spring 启动方式(例如依赖注入)这里是一个明显是 Spring 的代码示例。
import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*
@Component
public class MyBean {
@Value("${name}")
private String name;
// ...
}
If you are using some similar Framework such things could be easy archived.
如果您正在使用一些类似的框架,那么这些东西很容易存档。
If that is somehow not possible in your environment I had to code something like this:
如果这在您的环境中是不可能的,我必须编写如下代码:
public final class Configuration {
private Configuration() {
// make sure there is no instance of this class
}
public static final MySetting<DateFormat> setting = new SampleProperty();
public interface MySetting<T> {
T get();
}
private static final class SampleProperty implements MySetting<DateFormat> {
@Override
public DateFormat get() {
return new SimpleDateFormat("...");
}
}
// other inner classes that implement the MySetting interface
}
public static void main(final String[] args) {
Configuration.setting.get();
}
Benefits: - You can validate your properties how ever you want. - You can work with the java security manager if you like to
优点: - 您可以随时验证您的属性。- 如果您愿意,可以使用 java 安全管理器
Downsides: - You may have to maintain a bunch of code (this should be easier with lambda expressions) - Not that great as the way spring offers here for example.
缺点: - 您可能需要维护一堆代码(使用 lambda 表达式应该更容易) - 例如,不如 spring 提供的方式那么好。
A very similar approach I just found: https://stackoverflow.com/a/3931399/1248724
我刚刚发现的一种非常相似的方法:https: //stackoverflow.com/a/3931399/1248724
回答by ethanfar
In my opinion, the best approach to passing anything into your classes is using dependency injection. This would eliminate your need for Singletons, static constants and the likes.
在我看来,将任何东西传递到类中的最佳方法是使用依赖注入。这将消除您对单例、静态常量等的需求。
Depending on which DI you favor, here are some link solutions to the problem you describe:
根据您喜欢的 DI,以下是您描述的问题的一些链接解决方案: