这是我获取数据库连接的单例类。
我在这里有一个问题:为什么必须在单例类中包含一个私有构造函数(在整个应用程序中我只调用一次这个类)并且可以使用静态方法实现类的一个实例?
可以避免这个私有构造函数,还是它是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;
}
}
答案 0 :(得分:16)
否则每个人都可以创建一个类的实例,因此它不再是单例。对于单身人员,根据定义,只能存在一个实例。
答案 1 :(得分:6)
Singleton模式通常包含非公共构造函数,原因有两个。必须存在构造函数,因为如果根本没有构造函数,则包含公共默认构造函数。但是,如果你有一个公共构造函数,那么人们可以随意制作自己的单身人士(有人不可避免地会这样做,这意味着可以有不止一个)。
但是,它不一定是私人的。事实上,正如我所听到的那样,GoF指定的Singleton模式提到了 protected 构造函数,原因有些奇怪。关于继承的一些事情,我听说,但单身人士和继承人无论如何都不能很好地融合在一起。甚至可以拥有一个公共构造函数,只要它可以检测实例是否已存在并抛出异常或其他内容。这足以保证单一性。但这种情况并不常见,因为通过提供两种明显的方法来获取实例,这样做会使事情变得复杂 - 其中只有一种实际可行。如果您不希望外部代码能够创建第二个实例,为什么构造函数应该成为公共接口的一部分?
答案 2 :(得分:6)
如果你不需要延迟启动:
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;
}
}
是最好的方法,因为它是线程安全的。
答案 3 :(得分:5)
如果没有这样的私有构造函数,Java将为您提供默认的公共构造函数。然后,您可以多次调用此构造函数来创建多个实例。那就不再是单身人士了。
答案 4 :(得分:4)
对于singleton pattern,您使用私有构造函数来确保不能创建其他实例,否则它不会是单例。
答案 5 :(得分:3)
静态类与单例不同之处在于单例类强制始终最多只有一个实例。静态类没有实例,只是一组静态函数和静态数据。
因此,对于Singleton类,即一个最多只有一个实例的类,则需要私有构造函数。
在您的示例中,由于连接和dataSource成员,看起来Singleton类比静态类更合适。将这些成员设为私有,将构造函数设为私有,并提供引用静态ConnPoolFactory实例的静态方法。如果instance为null,则创建一个新的,否则只使用它。
答案 6 :(得分:3)
对于单例和实用类,您可以使用enum
这是一个最终类,并隐式定义私有构造函数。
enum Singleton {
INSTANCE
}
或
enum Utility {;
}
在上面的示例中,您有一个实用程序类,因为您没有实例字段,方法,也没有创建实例。
答案 7 :(得分:2)
你说的评论如果我是我的应用程序的完全拥有者,我将永远不会犯错误直接使用公共构造函数创建单例类的实例,但将使用静态方法来获取它。但在现实世界中,应用程序经常在多个开发人员之间切换。如果新开发人员不知道您只想在应用程序中使用该类的一个实例,则他/她可能会意外地使用公共构造函数创建另一个实例。
答案 8 :(得分:1)
这是强制性的。您的代码可能没问题,但是其他人可以使用此代码并实例化另一个对象,或者您可能会意外地执行此操作。这种方式很安全。
答案 9 :(得分:1)
单身清晰度:
确保仅需要为整个主堆栈创建一个对象(每个主类)。
如果您想满足上述声明,那么我们应该将构造函数作为私有变量。实际上,通过单例,我们得到了ref not object,这就是为什么它不是强制性的,然后我们可以在其他类中创建对象,但是我们不能访问引用(构造函数为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