Java 我应该使我的类应用程序是静态的吗?

Java 我应该使我的类应用程序是静态的吗?,java,static-classes,Java,Static Classes,我正在构建一个Java应用程序。我有一个名为Application的类,它包含用户对象和组对象的ArrayList。在类用户和组中,某些方法(例如向另一个用户发送消息)需要通过电子邮件、用户名或类应用程序中用户arraylist中的另一个字段获取另一个用户对象搜索。由于应用程序是容器类,所以我不希望在包含的类用户或组中包含它的实例 因为我只准备了一个应用程序类的实例,所以我想将这个类及其属性设置为静态,以便能够从用户类和组类访问搜索方法,但我也不确定这是一个好主意还是正确使用静态类。你认为这是对

我正在构建一个Java应用程序。我有一个名为Application的类,它包含用户对象和组对象的ArrayList。在类用户和组中,某些方法(例如向另一个用户发送消息)需要通过电子邮件、用户名或类应用程序中用户arraylist中的另一个字段获取另一个用户对象搜索。由于应用程序是容器类,所以我不希望在包含的类用户或组中包含它的实例

因为我只准备了一个应用程序类的实例,所以我想将这个类及其属性设置为静态,以便能够从用户类和组类访问搜索方法,但我也不确定这是一个好主意还是正确使用静态类。你认为这是对的还是有更好的选择?提前谢谢


编辑*另一个选项是将用户和组的属性ArrayList设置为静态,因为它们对于应用程序的所有可能实例都必须相同。你认为这样更好吗?

嗯,这看起来像是一个
单例
模式问题。您在类内声明一个
静态
字段,该字段保存该类的当前实例:

private static Application INSTANCE = null;
然后在方法中,您可以返回现有实例,也可以创建一个新实例,这样就始终存在一个实例:

public static Application getInstance(){
    if(INSTANCE == null){
        return new Application();
    }
    else return INSTANCE;
}
然后,使用此访问点,调用
静态
方法(无需先实例化类即可):


编辑:正如注释中所建议的,此类类的构造函数应该是私有的,以防止不受控制的外部实例化(就像在多线程中一样)

使用具有静态变量和函数的final类是一种方法。但将此类类称为“应用程序”可能不是最佳选择

最终类允许您从所有其他类访问这些变量和/或函数,而无需创建多个实例来获取这些静态数据


但是你应该考虑的是数据是如何“静态”的。如果部分变量不像用户列表那样是随时间增长的静态变量,那么最好只使用一个本身是静态的UserFactory,并管理类用户和“arraylist[user]users”,然后通过调用UserFactory.get(),set(),update()来处理它.

如果您确定要实现单例应用程序,我建议您这样做

公共枚举应用程序{
实例;
私有ArrayList用户列表;
//应用程序应包含的任何其他成员
}
但是,您应该知道,一般来说,
静态
代码正在破坏设计模式,这可能会在大规模应用程序中导致sirius问题(请注意了解更多关于依赖项注入与全局状态的信息)

这并不是说拥有
静态
代码总是不好的,而是通常应该为无状态实用程序方法或全局常量保留


无论如何,如果您决定实现一个singlton,请尝试在整个应用程序中只使用一个这样的singlton。如果您将其他类作为字段添加到真正的singlton上,那么其他类将成为“singlton”(如果有意义的话,您可以为singlton类创建一个私有的内部类型,以确保它不会从外部实例化)。这样可以避免静态初始化顺序问题(其中单例相互依赖,JVM“神奇地”初始化它们的顺序很重要)。

您是否尝试过向应用程序类添加静态修饰符?编译器说了什么?@JB Nizet它说这是非法的,但我不明白为什么。。。如果我将用户和组的属性ArrayList设置为静态,因为它们在所有可能的实例中都是相同的?它说这是非法的,因为顶级类不能是静态的。只有嵌套类。字段和方法可以是静态的,而不是类。因此,如果我实现UserFactory类,那么它应该包含存储系统内用户的ArrayList,然后应用程序和其他类应该调用UserFactory的方法来管理它们或搜索。我说得对吗?是的。实现一个(不是)公共最终类UserFactory(),该类包含所有静态变量,如List[User],添加函数以使用这些变量,并使构造函数私有(Singleton)。这是管理全局变量的一种方法,如果操作得当,是非常无害的。@avk-a
factory
应该是一个无状态类,它只构造实例,不保存它生成的实例。我看不出这样的工厂有什么帮助。在我看来,这似乎使应用程序过于复杂了。@elist-你完全正确。不应该被称为工厂。UserManager将是一个更好的选择。但我并不认为它会使应用程序过于复杂。只是一个简单的建议,在实现<代码>单例<代码>时,应该将构造函数<代码>设置为私有的<代码>,否则可以在他们想要的地方创建实例:-)+1,不过,对于其他情况,我的投票有时会出现,因为我的限制已经没有了:-)这是真的,我把这件事记下来,忘了。我来编辑
Application app = Application.getInstance();
public enum Application {
    INSTANCE;
    private ArrayList<User> userList;
    // Whatever other members your application should contain
}