繁体   English   中英

为什么在Singleton类中使用私有Constructor是强制性的

[英]Why is it mandatory to have private Constructor inside a Singleton class

这是我获取数据库连接的单例类。

我在这里有一个问题:为什么必须在单例类中有一个私有构造函数(因为在整个应用程序中我只调用一次这个类)并且可以使用静态方法实现类的一个实例?

这个私人构造函数可以避免,还是它是mantadatory?

 public class ConnPoolFactory {
        private static DataSource dataSource;
        private static Connection connection;

        private ConnPoolFactory() {
            System.out.println(" ConnPoolFactory cons is called ");
        }

        public static synchronized Connection getConnection() throws SQLException {

            try {

                if (connection == null) {
                    Context initContext = new InitialContext();
                    Context envContext = (Context) initContext
                            .lookup("java:/comp/env");
                    dataSource = (DataSource) envContext.lookup("jdbc/Naresh");
                    connection = dataSource.getConnection();
                } else {
                    return connection;
                }

            } catch (NamingException e) {
                e.printStackTrace();
            }

            return connection;

        }
    }

否则每个人都可以创建一个类的实例,因此它不再是单例。 对于单身人员,根据定义,只能存在一个实例。

Singleton模式通常包括非公共构造函数,原因有两个。 必须存在构造函数,因为如果根本没有构造函数,则包含公共默认构造函数。 但是,如果你有一个公共构造函数,那么人们可以随意制作自己的单身人士(有人不可避免地会这样做,这意味着可以有不止一个)。

但它不一定是私人的。 事实上,正如我所听到的那样,GoF指定的Singleton模式提到了受保护的构造函数,原因有些奇怪。 关于继承的一些事情,我听说,但单身和继承在任何方面都不能很好地发挥作用。

甚至可以拥有一个公共构造函数,只要它可以检测实例是否已经存在并抛出异常或其他内容(如果有)。 这足以保证单一性。 但这种情况并不常见,因为通过提供两种明显的方法来获取实例,这样做会使事情变得复杂 - 其中只有一种实际可行。 如果您不希望外部代码能够创建第二个实例,为什么构造函数应该成为公共接口的一部分?

如果你不需要延迟启动:

public class Singleton {
    private static final Singleton instance = new Singleton();

    // Private constructor prevents instantiation from other classes
    private Singleton() { }

    public static Singleton getInstance() {
            return instance;
    }
}

是最好的方法,因为是线程安全的。

如果没有这样的私有构造函数,Java将为您提供默认的公共构造函数。 然后,您可以多次调用此构造函数来创建多个实例。 那么它不再是单身人士班了。

对于单例模式,您使用私有构造函数来确保不能创建其他实例,否则它将不是单例。

静态类与单例不同,因为单例类强制始终最多只有一个实例。 静态类没有实例,只是一组静态函数和静态数据。

因此对于Singleton类,即一个最多只有一个实例的类,则需要私有构造函数。

在您的示例中,由于连接和dataSource成员,Singleton类看起来比静态类更合适。 将这些成员设为私有,将构造函数设为私有,并提供引用静态ConnPoolFactory实例的静态方法。 如果instance为null,则创建一个新的,否则只使用它。

对于单例和实用类,您可以使用enum ,它是最终类,并隐式定义私有构造函数。

enum Singleton {
     INSTANCE
}

要么

enum Utility {;

}

在上面的示例中,您有一个实用程序类,因为您没有实例字段,方法并且不创建实例。

你说的评论如果我是我的应用程序的完全拥有者,我将永远不会犯错误直接使用公共构造函数创建单例类的实例,但将使用静态方法来获取它。 但在现实世界中,应用程序经常在多个开发人员之间切换。 如果新开发人员不知道您只想在应用程序中使用该类的一个实例,则他/她可能会意外地使用公共构造函数创建另一个实例。

Singleton def:

确保只需要为整个主堆栈(每个主类)创建一个对象。

如果你想满足上面的语句,那么我们应该将构造函数作为私有。 实际上通过单例我们得到ref不反对这就是为什么它不是强制性的然后我们可以在其他类中创建对象但我们不能访问引用(Constructor as public)。

例如:

public class SingleTon {

    private static SingleTon s;
    public SingleTon() {}

    public static SingleTon getInstance() {
        if (s == null) {
            s = new SingleTon();
            System.out.println("ho ho");
        } else{
            return s;
        }
        return s;
    }
}

其他课程:

public class Demo {

    public static void main(String[] args) {
        //SingleTon s=SingleTon.getInstance();

        SingleTon s11=new SingleTon();
        SingleTon s12=new SingleTon();
        s11.getInstance();
        s12.getInstance();
    }
}

输出:

ho ho

这是强制性的。 您的代码可能没问题,但是其他人可以使用此代码并实例化另一个对象,或者您可能会意外地执行此操作。 这种方式很安全。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM