代码之家  ›  专栏  ›  技术社区  ›  Navin Israni

为什么单例设计模式中对象的访问器方法必须是“静态”的?

  •  0
  • Navin Israni  · 技术社区  · 8 年前

    在单例设计模式中,我们使用私有构造函数将对象的创建限制为单个对象。

    为了提供全局句柄,我们使用“公共静态”方法。

    我的问题是为什么这里需要静态?为什么不只是公开呢?

    2 回复  |  直到 8 年前
        1
  •  3
  •   Community CDub    4 年前

    简而言之:

    假设您有一个单例类:

    public class Singleton {
        ...
    }
    

    那么构造函数可能是私有的,这意味着您不能使用 new Singleton() 来自另一个班级。

    因此,访问Singleton类中的内容的唯一方法是使用 Singleton.methodName() Singleton.fieldName .

    但是为了做到这一点,这些方法和字段不能是对象的一部分,它们必须 static getSingleton() getInstance() 方法也不例外。

    假设您有一个单例类:

    public class Singleton {
        
    }
    

    新单例() 从每一个其他类,然后它将不再是一个单身。所以这个类现在看起来像这样。

    public class Singleton {
    
        private Singleton(){
    
        }
    
    }
    

    既然构造函数是私有的,这意味着您不能从另一个类实例化类,也可以从单例类内部实例化。因此,我们应该添加 getInstance() getSingleton() 方法

    public class Singleton {
    
        private Singleton(){
    
        }
    
        public Singleton getSingleton(){
            return null;
        }
    
    }
    

    但现在我们无法访问它,因为 getSingleton() 方法只能用于对象,我们不能从类外部实例化单例对象。所以 getSingleton() 需要通过使用访问 Singleton.getSingleton() 因此它必须成为一种静态方法。

    public class Singleton {
    
        private Singleton(){
    
        }
    
        public static Singleton getSingleton(){
            return null;
        }
    
    }
    

    到目前为止的答案应该回答了这个问题,但它不是一个函数式的单例类。因此,请继续阅读完整的答案。

    现在,我们还想从 getSingleton() 方法因此,我们还希望一个名为单例实例的字段指向单例类的实例。

    public class Singleton {
        private Singleton instance;
    
        private Singleton(){
    
        }
    
        public static Singleton getSingleton(){
            return instance;
        }
    
    }
    

    但是现在,实例字段不能被get访问 getSingleton() 方法,因为现在编写类的方式是实例是对象的字段,而不是类,所以实例字段也必须变成静态的。

    public class Singleton {
        private static Singleton instance;
    
        private Singleton(){
    
        }
    
        public static Singleton getSingleton(){
            return instance;
        }
    
    }
    

    现在,最后一个问题是变量实例没有在任何地方实例化,所以它总是返回 null .所以我们必须在 getSingleton() 如果实例是 无效的 然后创建 新单例() 并使实例字段指向它。

    public class Singleton {
        private static Singleton instance;
    
        private Singleton(){
    
        }
    
        public static Singleton getSingleton(){
            if(instance == null){
                instance = new Singleton();
            }
            return instance;
        }
    
    }
    

    如果您想要一个线程安全的单例类,您可以使用类似这样的方法(建议 Boris the Spider ):

    public enum Singleton {
        INSTANCE;
        private Singleton(){
            // TODO
        }    
    }
    

    现在单例完成了。

        2
  •  1
  •   ΦXocę 웃 Пepeúpa ツ    8 年前

    如果该方法是公共的,没有静态的,则需要类的实例才能调用该方法。这没有任何意义。

    相反,静态方法可以在没有实例的情况下调用,因为它们属于类