是否可以使用使用构造函数参数的枚举来创建Java单例

时间:2013-09-18 21:24:58

标签: java constructor enums singleton 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]);
            }
    }

我似乎无法理解具有普通Java类构造函数的语法,我也可以从主例程中传递args。我的初始化程序似乎是一种难闻的气味 - 但它是我能够想到的最好的。有什么建议吗?

3 个答案:

答案 0 :(得分:1)

你的方法的问题源于enum与单身人士一样好的主要原因。

让我建议用Schrödinger's cat思想实验进行类比。 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课程的任何地方访问你的单身人士,它可能会中断。

答案 1 :(得分:0)

不,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不是你想要的,特别是如果你想给它赋值运行时。

答案 2 :(得分:0)

你可能意味着这样的事情:

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 tutorial中的。你显然没有处理一些常数。