Java单例方法允许对象的多个实例

时间:2015-11-19 12:01:56

标签: java singleton

我最初编写了以下代码。目的是确保在任何时间点只创建一个类的一个对象。

public class singleinstance {
private static int instance;

public singleinstance(){
    if(instance != 0){
        throw new IllegalStateException("More than one instance");
    }
    System.out.println(instance);
    instance ++;
    System.out.println(instance);
}
}

之后,当我检查互联网以查看这是否是最佳方式时,我遇到了singleton这个词,并使用了私有构造函数,并遇到了This link 我在其接受的答案部分尝试了相同的代码,但是通过定义计数器变量并打印它,并且可以看到类的实例数量多于一个。我正在粘贴下面的代码。

public class Singleton {
private static int counter=0;
private static Singleton instance;

/**
 * A private Constructor prevents any other class from
 * instantiating.
 */
private Singleton() {
    // nothing to do this time
}

/**
 * The Static initializer constructs the instance at class
 * loading time; this is to simulate a more involved
 * construction process (it it were really simple, you'd just
 * use an initializer)
 */
static {
    instance = new Singleton();
}

/** Static 'instance' method */
public static Singleton getInstance() {
    return instance;
}

// other methods protected by singleton-ness would be here...
/** A simple demo method */
public int demoMethod() {
    counter++;
    return counter;
}
}

Singletontest.java

public class Singletontest {
public static void main(String[] args) {
    Singleton tmp = Singleton.getInstance();
    System.out.println(tmp.demoMethod());
    Singleton tmp1 = Singleton.getInstance();
    System.out.println(tmp1.demoMethod());
}
}

测试类在执行时打印12,这意味着使用单例类创建了类的两个实例。如果这是可能的,为什么它被认为是单身?请理解我的理解。

EDIT ::  对方法的调用再次增加了该值。但同样,我可以多次调用方法tmp1.demoMethod(), tmp.demoMethod(),这使我认为tmp和tmp1是创建的两个对象。我如何确认,或者我可以研究什么,以确认这只是一个单一的实例?

7 个答案:

答案 0 :(得分:1)

在您的示例中,tmp和tmp1是同一个对象实例。 您可以通过打印两个对象来检查它:

System.out.println(tmp);
System.out.println(tmp1);

之后,您在同一对象上调用该方法两次,并且计数器递增两次。 但是只创建了一个Singleton对象

答案 1 :(得分:1)

你的结论是不正确的,增加数字意味着完全相反(你只有一个实例)。但是你的计数器是静态的,这意味着它由所有实例共享,因此它不能用作参数

  1. 使计数器非静态。这意味着Singleton类的每个实例都将拥有它的'自己的计数器从0开始
  2. 然后调用您的代码。如果你得到1,2,你只有一个Singleton类的实例。如果你得到1,1,那就意味着你有两个Singleton类的实例。但那不会发生
  3. 顺便说一下,tmp和tmp1是对同一个实例的两个引用

答案 2 :(得分:1)

这里tmp和tmp1是同一个对象实例。如果你尝试打印tmp和tmp1它将是相同的。我的意思是它指向同一个对象。

答案 3 :(得分:0)

它不是在创建多个实例。您的静态变量只会增加。

将静态视为类变量,而非实例变量。

答案 4 :(得分:0)

此处您只从Singleton对象调用方法。第一次调用Singleton.getInstance()时,您将获得counter变量值设置为0的对象。

之后,您通过单例对象调用demoMethod,它会将counter的值增加到1.再次通过Singleton.getInstance()检索对象时,它将为您提供相同的对象实例变量值为1,以及当你通过它调用demoMethod时它打印2的原因。

答案 5 :(得分:0)

<强>现有: 您已将setup.py变量声明为静态/类变量(在同一类的多个实例之间共享)。

counter

在方法private static int counter=0; 内,您使用demoMethod运算符递增计数器,这样每次在实例上调用方法时,计数器值都会增加 - 这就是它打印为1的原因,2

您可以尝试这样:

++变量声明为类

中的实例变量
counter

现在输出将为1,1

答案 6 :(得分:0)

我更喜欢这种方式来创建Singleton类。

public class Singleton {

private static Singleton instance;

private Singleton() {  
}

public static Singleton getInstance() {
    if(instance == null){
       instance = new Singleton();  
    }
    return instance;
}

}