JAVA单例不起作用

时间:2018-06-22 07:08:54

标签: java

我增强/测试了我发现的编码 ArrayList initialized/accessed using Singleton class

import java.util.ArrayList;

public class SingletonArrayList {

    private static SingletonArrayList mInstance;
    private static ArrayList<String> list = null;

    public static SingletonArrayList getInstance() {
        if (mInstance == null)
            mInstance = new SingletonArrayList();
        SingletonArrayList.list.add("a");
        SingletonArrayList.list.add("b");
        SingletonArrayList.list.add("c");
        return mInstance;
    }

    private SingletonArrayList() {
        list = new ArrayList<String>();
    }

    // retrieve array from anywhere
    public ArrayList<String> getArray() {
        return SingletonArrayList.list;
    }

}

然后我创建了一个测试类,在其中我两次调用了上述单例:

import java.util.ArrayList;

public class TestSingletonArrayList {

    public static void main(String[] args) {


        ArrayList<String> array = SingletonArrayList.getInstance().getArray();
        for (int i = 0; i < array.size(); i++) {
            System.out.println(array.get(i));
        }
        System.out.println("-----------");
        ArrayList<String> array2 = SingletonArrayList.getInstance().getArray();
        for (int i = 0; i < array2.size(); i++) {
            System.out.println(array2.get(i));
        }

    }

}

输出为:

a
b
c
-----------
a
b
c
a
b
c

这似乎很奇怪。我希望单例类的第二次调用只会返回a,b,c而不返回a,b,c,a,b,c

怎么了?我只期望a,b,c,因为它是单身人士

谢谢,问候 马里奥

2 个答案:

答案 0 :(得分:8)

像这样更改它,

public class SingletonArrayList {
    private static SingletonArrayList mInstance;
    private static ArrayList<String> list = null;

    public static SingletonArrayList getInstance() {
        if (mInstance == null) {
            mInstance = new SingletonArrayList();
            SingletonArrayList.list.add("a");
            SingletonArrayList.list.add("b");
            SingletonArrayList.list.add("c");
        }

        return mInstance;
    }

    private SingletonArrayList() {
        list = new ArrayList<String>();
    }

    // retrieve array from anywhere
    public ArrayList<String> getArray() {
        return SingletonArrayList.list;
    }

}

这里的问题是您必须创建对象并立即对其进行初始化。在您的解决方案中,您只需创建一次,然后为每次调用分别添加项目。它仍然只有一个实例,但是您每次getInstance调用时都向该单例添加元素,这很直观。

答案 1 :(得分:2)

使用代码,每次调用单例实例时(因为只有下一条指令引用了if),就添加了三个元素abc,因此第一次通话时您有abc,而第二次通话时您有abcabc

仅在创建实例时才需要添加它们:

public static SingletonArrayList getInstance() {
    if (mInstance == null){
        mInstance = new SingletonArrayList();
        SingletonArrayList.list.add("a");
        SingletonArrayList.list.add("b");
        SingletonArrayList.list.add("c");
    }
    return mInstance;
}

此外,真实的Singleton pattern具有一个final类和一个final实例,不允许对其进行修改,您的lazy初始化很好,但是您可以对其进行修改,所以真正的是:

  • 最后一堂课
  • 私有构造函数
  • 静态最终实例
public final class SingletonArrayList {

    private static final SingletonArrayList mInstance = new SingletonArrayList();
    private static ArrayList<String> list = null;

    public static SingletonArrayList getInstance() {
        return mInstance;
    }

    private SingletonArrayList() {
        list = new ArrayList<String>();
        SingletonArrayList.list.add("a");
        SingletonArrayList.list.add("b");
        SingletonArrayList.list.add("c");
    } 

}