在面向对象编程中,单例类是一个一次只能有一个对象(类的一个实例)的类。第一次之后,如果我们尝试实例化Singleton类,新变量也会指向创建的第一个实例。因此,无论我们通过任何实例对类内的任何变量进行什么修改,都会影响所创建的单个实例的变量,并且如果我们通过定义的该类类型的任何变量访问该变量,则该变量是可见的。
在将类定义为单例类时,也就是在设计单例类时,请记住关键点:
- 将构造函数设为私有。
- 编写一个静态方法,该方法具有此单例类的返回类型对象。这里,惰性初始化的概念被用来编写这个静态方法。
单身人士课程的目的
单个类的主要目的是将对象创建的数量限制为仅一个。这通常可以确保对资源进行访问控制,例如套接字或数据库连接。
使用singleton类不会造成内存空间浪费,因为它会限制实例的创建。因为对象创建只会发生一次,而不是每次发出新请求时都创建它。
我们可以根据需要重复使用这个单一对象。这就是为什么多线程和数据库应用程序大多使用Java中的单例模式进行缓存、日志记录、线程池、配置设置等。
例如,我们有一个许可证,我们只有一个数据库连接,或者假设如果我们的JDBC驱动程序不允许我们进行多线程处理,那么Singleton类就会出现,并确保每次只有一个连接或一个线程可以访问该连接。
如何在Java中设计/创建单例类?
要创建singleton类,我们必须遵循以下步骤:
1. 确保该类只存在一个实例。
2. 通过以下方式提供对该实例的全局访问:
- 声明类的所有构造函数都是私有的。
- 提供返回实例引用的静态方法。惰性初始化概念用于编写静态方法。
- 实例存储为私有静态变量。
单例类的例子是 运行时类、操作Servlet、服务定位器 .私有构造函数和工厂方法也是singleton类的一个示例。
普通班和单身班的区别
在实例化类对象的过程中,我们可以将单例类与普通类区分开来。为了实例化一个普通类,我们使用java构造函数。另一方面,为了实例化一个单例类,我们使用getInstance()方法。
另一个区别是,普通类在应用程序生命周期结束时消失,而单例类不会随着应用程序的完成而销毁。
单身阶级模式的形式
单例设计模式有两种形式,分别是:
- 早期实例化: 对象创建在加载时进行。
- 延迟实例化: 根据需求创建对象。
实施: 让我们简单介绍一下singleton类与java中的普通类的区别。这里的区别在于实例化,对于普通类我们使用构造函数,而对于单例类我们使用构造函数 getInstance()方法 我们将在下面的示例1中看到这一点。一般来说,为了避免混淆,在定义这个方法时,我们也可以使用类名作为方法名,如下例2所示。
例1:
JAVA
// Java program implementing Singleton class // with using getInstance() method // Class 1 // Helper class class Singleton { // Static variable reference of single_instance // of type Singleton private static Singleton single_instance = null ; // Declaring a variable of type String public String s; // Constructor // Here we will be creating private constructor // restricted to this class itself private Singleton() { s = "Hello I am a string part of Singleton class" ; } // Static method // Static method to create instance of Singleton class public static Singleton getInstance() { if (single_instance == null ) single_instance = new Singleton(); return single_instance; } } // Class 2 // Main class class GFG { // Main driver method public static void main(String args[]) { // Instantiating Singleton class with variable x Singleton x = Singleton.getInstance(); // Instantiating Singleton class with variable y Singleton y = Singleton.getInstance(); // Instantiating Singleton class with variable z Singleton z = Singleton.getInstance(); // Printing the hash code for above variable as // declared System.out.println( "Hashcode of x is " + x.hashCode()); System.out.println( "Hashcode of y is " + y.hashCode()); System.out.println( "Hashcode of z is " + z.hashCode()); // Condition check if (x == y && y == z) { // Print statement System.out.println( "Three objects point to the same memory location on the heap i.e, to the same object" ); } else { // Print statement System.out.println( "Three objects DO NOT point to the same memory location on the heap" ); } } } |
Hashcode of x is 558638686Hashcode of y is 558638686Hashcode of z is 558638686Three objects point to the same memory location on the heap i.e, to the same object
输出说明:
在单身学生的课堂上,当我们第一次打电话给 getInstance()方法 ,它创建一个名为single_instance的类对象,并将其返回给变量。由于单_实例是静态的,所以它会从null更改为某个对象。下一次,如果我们尝试调用getInstance()方法,因为single_instance不为null,它将返回到变量,而不是再次实例化Singleton类。这部分由if条件完成。 在主类中,我们通过调用静态 方法getInstance() .但实际上,在创建对象x之后,变量y和z指向对象x,如图所示。因此,如果我们改变对象x的变量,当我们访问对象y和z的变量时会反映出来。同样,如果我们改变对象z的变量,当我们访问对象x和y的变量时会反映出来。 现在我们已经完成了示例1的所有方面,并且已经实现了相同的功能,现在我们将使用与类名相同的方法名来实现Singleton类。
例2:
JAVA
// Java program implementing Singleton class // with method name as that of class // Class 1 // Helper class class Singleton { // Static variable single_instance of type Singleton private static Singleton single_instance = null ; // Declaring a variable of type String public String s; // Constructor of this class // Here private constructor is is used to // restricted to this class itself private Singleton() { s = "Hello I am a string part of Singleton class" ; } // Method // Static method to create instance of Singleton class public static Singleton Singleton() { // To ensure only one instance is created if (single_instance == null ) { single_instance = new Singleton(); } return single_instance; } } // Class 2 // Main class class GFG { // Main driver method public static void main(String args[]) { // Instantiating Singleton class with variable x Singleton x = Singleton.Singleton(); // Instantiating Singleton class with variable y Singleton y = Singleton.Singleton(); // instantiating Singleton class with variable z Singleton z = Singleton.Singleton(); // Now changing variable of instance x // via toUpperCase() method x.s = (x.s).toUpperCase(); // Print and display commands System.out.println( "String from x is " + x.s); System.out.println( "String from y is " + y.s); System.out.println( "String from z is " + z.s); System.out.println( "" ); // Now again changing variable of instance x z.s = (z.s).toLowerCase(); System.out.println( "String from x is " + x.s); System.out.println( "String from y is " + y.s); System.out.println( "String from z is " + z.s); } } |
String from x is HELLO I AM A STRING PART OF SINGLETON CLASSString from y is HELLO I AM A STRING PART OF SINGLETON CLASSString from z is HELLO I AM A STRING PART OF SINGLETON CLASSString from x is hello i am a string part of singleton classString from y is hello i am a string part of singleton classString from z is hello i am a string part of singleton class
输出说明: 在singleton类中,当我们第一次调用singleton()方法时,它会创建一个名为single_instance的singleton类对象,并将其返回给变量。由于单_实例是静态的,所以它会从null更改为某个对象。下次如果我们尝试调用Singleton()方法,因为single_实例不为null,它将返回到变量,而不是再次实例化Singleton类。
本文由 帕万·戈帕尔·拉亚帕蒂 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。