单身java模式

时间:2011-02-11 12:34:37

标签: java

我仍然可以通过使用构造函数来实例化,尽管在类定义中它已被声明为私有构造函数???这是代码片段:

public class Singleton {

  private static Singleton instance;
  private String name;

  /* Private constructor prevents other classes from instantiating */
  private Singleton(String name) {
    this.name = name;
    // Optional code
  }

  /*
   * Static factory method that creates instance instead of constructor.
   * Synchronization helps to block any attempt to instantiate from simultaneous
   * thread hence break concept of singleton.
   * This method uses a technique known as lazy instantiation.
   */
  public static synchronized Singleton getInstance(String name) {
    if (instance == null) {
      instance = new Singleton(name);
    }
    return instance;
  }

  /* Override Object clone method to avoid cloning */
  @Override
  public Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException();
  }

  public String getName() {
    return name;
  }

  /* Example of using singleton object */
  public static void main(String[] args) {
    Singleton a = new Singleton("Hoang");
    Singleton b = new Singleton("Shiha");
    System.out.println(a.getName());
    System.out.println(b.getName());
  }

4 个答案:

答案 0 :(得分:6)

您仍然可以实例化它,因为在同一个类中的test main()方法可以访问私有构造函数:private表示“仅对此类可用”。

将你的考试放在另一个班级,你会得到你期望的。

答案 1 :(得分:1)

您的测试方法属于同一类 - >它可以访问私人会员&方法

有关Java中Singleton模式的更多信息,请参阅this问题:)

答案 2 :(得分:1)

您可以实例化单例,因为您是从Singleton的类定义中的方法执行的(提示,您可以访问定义它们的类中的私有方法。

尝试从您的Singleton的外部执行此操作,它将失败。另一方面,Singleton通常定义为 final (非常罕见,您需要扩展Singleton类)。


另一方面,人们通常会在默认(以及 私有 )构造函数中设置某种防护条件(.ie。抛出UnsupportedOperationException)以防止意外(或恶意攻击)通过反射访问它。

  /* default constructor made private and defended against reflection access */
  private Singleton() {
    throw new UnsupportedOperationException("naughty boy");
  }

答案 3 :(得分:1)

为了确保只将其实例化一次,您可以使用Singleton Enum模式:

public enum MySingleton {
    INSTANCE("My singleton name");

    private MySingleton(String name) {
        this.name = name;
    }

    private String name;
    public String getName() {
        return this.name;
    }
}

enum在某种程度上是共享相同界面的单例列表