【问题标题】:Is it reasonable to use a static instance in Java?在Java中使用静态实例是否合理?
【发布时间】:2013-06-24 14:23:26
【问题描述】:

我在谷歌上真的找不到这个问题的答案,所以就这样吧。

是否可以使用静态对象以便程序的其余部分可以引用该对象? 我不完全知道如何澄清我的问题,所以我只显示示例代码。

public class Client {

    Frame f;
    private static Client mainClient;

    public static void main(String[] args){
        new Client().init();
    }

    private void init(){

        mainClient = this;
        f = new Frame();

    }

    public static Client getClient() {
        return mainClient;
    }

    public Frame getFrame(){
        return f;
    }   
}

那么,是否可以在整个程序中使用 getClient() 方法来访问 Frame 对象,而不是将其作为参数发送给我创建的(大多数)对象?框架在整个程序中都使用,添加它作为参数只是为每个构造函数添加一个参数。

谢谢

【问题讨论】:

  • 请务必注意,实际上并不存在“静态实例”之类的东西。有静态的变量,但对象本身并不是静态的。
  • @Jtvd78 简短的回答是:这是绝对可以接受的。如果您使用线程,请注意线程安全。
  • 值得问一下:1)在这个应用程序的生命周期中是否总是只有一个Frame,2)程序的所有部分是否真的需要访问整个Frame,以及3 ) 是否应该共享数据模型而不是 Frame。
  • 为了澄清,只有一个客户端实例,它只生成一个框架实例。这贯穿于整个计划。至于线程安全,有人可以澄清为什么这不是线程安全的吗?此外,您提到共享数据模型可能是更好的选择。我会考虑作为一种选择

标签: java parameters static constructor client


【解决方案1】:

取决于不止一件事...

1) 用法。您是否希望能够说 MyClass.getClient() 并获得对 Client 变量的引用? 如果您的目标是单身人士-是的。如果您的目标是一件非常方便的事情-如果安全的话是可以的,如果您只想让它随处可见-不。如果从错误的地点/时间访问它会导致崩溃和错误 - 不会。

2) 人们会使用你暴露的任何东西,期间。如果他们看到你的代码像这样获取客户端,他们也会在不合适的时候使用它,那么它会导致很多错误吗? :)

3) 设计你真的需要它吗?像争论一样传递它比在任何时候都绝对访问它更干净吗?

衡量这些后,您再决定。这看起来像它构建并且工作正常。但是任何需要这种不受限制的访问(上面提到的任何时间访问)来访问特定于运行时的东西可能都不是最好的方法。适合家庭作业的方法可能不适用于企业软件。

【讨论】:

  • +1:适用于家庭作业的软件可能不适用于企业软件这是纯金。
【解决方案2】:

要了解在您的情况下是否可以使用单例模式,您应该问“该组件在应用程序的生命周期内是否保持不变?”,如果是,那么最好将其隔离在一个类中自己的。

【讨论】:

    【解决方案3】:

    您所描述的称为singleton pattern。尽管有一些批评,但它是一种经常使用的模式。

    将对象提供给每个构造函数的第二种替代方法是dependency injection 框架。对于 Java,最佳选择之一是 Spring

    【讨论】:

    • 作为 Spring 的替代品,我推荐 guice
    • @mariosangiorgio 作为 Java EE 5+ 环境中 Spring 和 Guice 的替代品,我建议使用 EJB 3 和/或 CDI。
    【解决方案4】:

    这样做是可以的。阅读 singleton pattern

    对您很有帮助

    【讨论】:

    • "OK" 有点言过其实了。如今,在大多数情况下,Singleton 被广泛认为是一种反模式。主要是因为人们往往不知道应该在哪里和不应该使用它,最终把所有东西都变成了单例。 :P
    【解决方案5】:

    您基本上是在问是否可以使用单例模式。是的。但问题是您必须确保不在非 GUI 线程中执行 GUI 操作。通过允许访问 Frame 类,您可以打开它以防止可能的滥用。我假设你是唯一的程序员,所以要小心处理它。

    【讨论】:

      【解决方案6】:

      您刚刚创建了SingleTon Pattern 的变体。当您在整个项目中只需要该对象的一个​​实例时,将使用静态对象。

      单例的基本结构是

      public class Client {
          private static Client mainClient;
      
      
          private void Client (){
               // do initial tasks
          }
      
          public static Client getClient() {
              if(mainClient == null)
                  mainClient = new Client();
              return mainClient;
          }
      
          public Frame getFrame(){
              return f;
          }   
      }
      

      所以你可以使用

      Client.getClient().getFrame();
      

      【讨论】:

      • 不确定他是否想要一个实例,或者易于访问,就是这样...... :)
      【解决方案7】:

      嗯,这种单例模式的实现是我最讨厌的。好的,编写代码真的很容易,但是稍后,如果必须更改某些内容,则必须在数百万个地方进行更改。对于单例模式,我会使用 依赖注入 - 控制反转 模式和 单例工厂 模式,并将 static 变量专门用于 constants(例如字符串、整数...)。

      关于你的问题,一切都可以接受。实施取决于您的项目要求。

      【讨论】:

      • @André:是的,每个结构和概念在某些情况下都有一些用途。如果没有,它就不会存在。最大的问题是知道特定概念在什么背景下有用。
      • @André 对企业软件有用的东西可能不适用于家庭作业,反之亦然。
      • 有一些用处并不代表可以接受。我同意这取决于上下文,但在编程中你也可以做很多我永远不会接受的事情。
      • @Andre:这是正确的词——你。在某些情况下,课程老师/助教,在其他一些情况下 - 购买了您部门的代码的无知的客户,这些代码是在严格的指导下生产的,并且在从未接触过代码的经理的监督下......在正确的情况和背景下,一切都是可以接受的:D
      【解决方案8】:

      对于常量/不可变对象,使用静态实例是完全可以的。

      至于可变对象,这取决于。在具有一个线程的简单程序中,它运行良好。但是,如果它是多线程或集群的,则应谨慎使用单例或根本不使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-18
        • 1970-01-01
        • 1970-01-01
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多