代码之家  ›  专栏  ›  技术社区  ›  anon

如何多次实例化一个单例?

  •  7
  • anon  · 技术社区  · 15 年前

    我的代码里需要一个单子。我用Java实现了它,效果很好。我这样做的原因是为了确保在多个环境中,这个类只有一个实例。

    但是现在我想用一个单元测试在本地测试我的单例对象。因此,我需要模拟这个单例的另一个实例(来自另一个设备的对象)。那么,是否有可能为了测试目的再次实例化一个单例,或者我必须模拟它?

    9 回复  |  直到 15 年前
        1
  •  9
  •   Abhinav Sarkar    15 年前

    可以使用反射调用单例类的私有构造函数来创建该类的新实例。

    class MySingleton {
        private MySingleton() {
        }
    }
    
    class Test {
        public void test() throws Exception {
            Constructor<MySingleton> constructor = MySingleton.class.getConstructor();
            constructor.setAccessible(true);
            MySingleton otherSingleton = constructor.newInstance();
        }
    }
    
        2
  •  17
  •   Oded    15 年前

    单例的要点是只能实例化一次。

        3
  •  17
  •   Sjoerd    15 年前

    如果使用依赖注入,可以让框架为您创建单例。singleton不防范其他实例(即它有一个公共构造函数),但是依赖注入框架只实例化一个实例。在这种情况下,您可以为测试创建更多的实例,并且您的对象不会被单例代码弄乱。

        4
  •  6
  •   JSBÕ±Õ¸Õ£Õ¹    15 年前

    根据定义,单例只能实例化一次。但是,单元测试需要 单例是一个强有力的迹象,表明你的对象 ,您应该重新考虑单例设计。

        5
  •  3
  •   matt b    15 年前

    我不得不发表这一系列关于单例如何破坏可测试性和糟糕的设计选择的文章:

        6
  •  2
  •   Stefan Valianu    15 年前

    你需要一个明确的第二个单子有什么特别的原因吗?

        7
  •  1
  •   Joel    15 年前

    getInstance2 看起来是这样的:

    class MySingleton
    {
        private MySingleton(){}
        private static MySingleton instance1 = new MySingleton();
        private static MySingleton instance2 = new MySingleton();
    
        public static MySingleton getInstance(){ return instance1; }
        public static MySingleton getInstance2(){ return instance2; }
    }
    
        8
  •  0
  •   Prashant Kumar Rye Bryant    11 年前

    Singleton ston=Singleton.getInstance(); 将返回单例对象。通过使用“ston”对象,如果调用 createNewSingleTonInstance()

    public class Singleton {
    
    private String userName;
    private String Password;
    private static Singleton firstInstance=null;
    private Singleton(){}
    
    
    public static synchronized Singleton getInstance(){
        if(firstInstance==null){
            firstInstance=new Singleton();
            firstInstance.setUserName("Prathap");
            firstInstance.setPassword("Mandya");
        }
        return firstInstance;
    }
    
    
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserName() {
        return userName;
    }
    public void setPassword(String password) {
        Password = password;
    }
    public String getPassword() {
        return Password;
    }
    
    public Singleton createNewSingleTonInstance(){
        Singleton s=new Singleton();
        s.setUserName("ASDF");
        s.setPassword("QWER");
        return s;
    }
    }
    
        9
  •  0
  •   Winston    9 年前

    您可以在地图上保留一个键,并用键填充实例

    public class MultiSingleton {
    /**** Non-static Global Variables ***/
    String status = "";
    private BaseSmartCard bsc;
    /***********************************/
    private static Object lockObject = new Object();
    private String serialNo;
    
    private static Map<String, MultiSingleton> mappedObjects = new TreeMap<String, MultiSingleton>();
    
    protected MultiSingleton() {
    
    }
    
    
    public static MultiSingleton getInstance(String serialNo,long slotNo){
        if (mappedObjects.isEmpty() || !mappedObjects.containsKey(serialNo)) {
            MultiSingleton instance = new MultiSingleton();
            instance.setSerialNo(serialNo);
            mappedObjects.put(serialNo, instance);
            return instance;
        } else if (mappedObjects.containsKey(serialNo)) {
            return mappedObjects.get(serialNo);
        }else {
            return null;
        }
    }