繁体   English   中英

是否有可能使用使用构造函数参数的枚举的Java单例

[英]Is it possible to have a Java singleton using an enum that uses constructor arguments

 public enum Singleton  {
            INSTANCE;
            String fromLocation;
            String toLocation;

            private void initialise(String fromLocation, String toLocation) {
                this.fromLocation = fromLocation;
                this.toLocation = toLocation;
            }

            public static void main(String[] args) {
                Singleton s = INSTANCE;
                s.initialise(args[0],args[1]);
            }
    }

我似乎无法理解语法是否具有可以从主例程传递args的普通Java类构造函数。 对我而言,初始化例程似乎难闻的气味-但这是我能想到的最好的方法。 有什么建议么?

您的方法存在的问题源于enum与单例一样好的主要原因。

让我提出一个类似薛定ding的猫思维实验的类比。 enum就像猫的状态一样,当盒子被打开并永远保持这种状态时,它立即被完全知道。 这是通过enum的性质来保证的,即,尽管许多人在看盒子的时候,实际上只是导致猫处于状态的第一位观看者才是猫的状态。 其他所有人都看到了那一刻的确切副本。

因此,您有两种方法可以将外部数据安装到enum的最终状态。 您可以保证是第一个打开盒子的人,或者-我在这里稍作类推-您教猫快速伸出手并抓住盒子第一次打开时的状态。

选项1与实现单例一样复杂。 绝对确定自己是第一位几乎是不可能的。

因此,选项2可能类似于:

public enum Singleton {

  INSTANCE;
  final String fromLocation;
  final String toLocation;

  private Singleton () {
    // Reach out.
    this.fromLocation = App.args[0];
    this.toLocation = App.args[1];
  }
}

您的App入口点如下所示:

class App {
  static String[] args;

  public static void main(String args[]) {
    App.args = args;
  }
}

这里有可怕的警告。 首先,如果您未在App.main启动它,则每个使用您的单例的应用程序都会中断。 其次,如果您在App类中的任何位置访问您的单例,它可能会中断。

不, enum构造函数的工作方式是

public enum Singleton {
     A("from", "too"),
     B("from2", "too2");

     private String from, to;

     private Singleton(String from, String too) {
         this.from = from;
         this.too = too;
     }
}

您真正要实现的目标是什么? enum可能不是您想要的,特别是如果您希望为其分配运行时值。

您的意思可能是这样的:

public class Singleton {
  private static Singleton instance;
  public static void getInstance() {
    if (instance == null)
      throw new IllegalStateException("Singleton not initialized!");
    return instance;
  }
  public static void init(String from, String to) {
    if (instance != null)
      throw new IllegalStateException("Singleton already initialized!");
    instance = new Singleton(from, to);
  }
  private final String from;
  private final String to;
  private Singleton(String from, String to) {
    this.from = from;
    this.to = to;
  }
}

显然,这不是线程安全的。但是,老实说,最好使用像Spring或Guice这样的依赖注入框架。 从长远来看,您代码中的Singleton.getInstance()调用不是您想要的...

为什么不使用/定义枚举? 它说: “枚举类型是一种特殊的数据类型,它使变量成为一组预定义的常量。” Java教程中 而且您显然没有处理某些常量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM