Java 单例类
本教程将在定义级别讨论单例类并强调其重要性。我们将描述编写 Java 单例类的各种设计模式,并借助代码示例对其进行解释。
Java 中的单例类
Java 单例类允许我们一次只创建该类的一个实例,该实例通过这个单一实例(也称为类的对象)全局服务于所有类。单例类不同于用于特定目的的普通类。
它包括避免类的不必要的实例化并确保一次只存在一个对象。它可以节省内存并加快工作速度。
请参阅下面的代码,其中我们有 ABC
和 XYZ
类。ABC
类有一个名为 method1
的方法,它打印字符串 "Hi"
。
我们在 XYZ
类中创建类 ABC
的实例来调用驻留在类 ABC
中的 method1
,我们创建另一个名为 ABC
的实例并再次调用 method1
以在下面打印"Hi"
XYZ
类。现在,我们有两个名为 object1
和 object2
的实例(对象),它们拥有不同的引用,但调用同一类的相同函数。
我们创建了类 ABC
的两个对象,它们是类的不必要实例化。我们可以对单个对象做同样的工作。
其次,每当我们创建一个对象时,它都会占用内存中的空间,这意味着我们通过创建同一个类的多个对象来浪费内存。这就是我们使用单例类来避免这些情况的地方。
示例代码:
public class ABC {
// constructor
public ABC() {}
// method1
public void method1() {
System.out.println("Hi");
}
}
public class XYZ {
// first instance of ABC class
ABC object1 = new ABC();
object1.method1();
// second instance of ABC class
ABC object2 = new ABC();
object2.method1();
}
单例类在各种应用程序中非常有用,包括日志记录、线程池、配置设置、缓存、数据库应用程序等。
在 Java 中使用各种方法使用单例类
在 Java 编程中编写单例类有多种方法,计算机程序员可以从中选择。但是所有方法都属于以下单例类的任何一种设计模式。
- 延迟初始化
- 早期初始化
对于我们在编写单例类时使用的任何方法,都应考虑以下因素。
- 类的构造函数必须是
private
。 - 单例类必须有一个
静态
方法来返回这个(单例)类实例。
使用延迟初始化方法的 Java 单例类
示例代码(Singleton.java
):
class Singleton {
private static Singleton object = null;
public String message;
private Singleton() {
message = "Hi I live in the Singleton class";
}
public static Singleton getInstance() {
if (object == null)
object = new Singleton();
return object;
}
}
示例代码(Test.java
):
public class Test {
public static void main(String args[]) {
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
Singleton obj3 = Singleton.getInstance();
System.out.println("Hashcode of obj1 is " + obj1.hashCode());
System.out.println("Hashcode of obj2 is " + obj2.hashCode());
System.out.println("Hashcode of obj3 is " + obj3.hashCode());
if (obj1 == obj2 && obj2 == obj3) {
System.out.println("Three instances reference to the same memory location");
} else {
System.out.println("All are not referencing to the same memory location");
}
}
}
输出:
Hashcode of obj1 is 1490180672
Hashcode of obj2 is 1490180672
Hashcode of obj3 is 1490180672
Three instances reference to the same memory location
在此方法中,仅在需要时创建类对象。使用这种方法,我们可以避免对 Singleton.java
类进行不必要的实例化。
在 Singleton.java
类中,我们创建了该类的 private static
对象(实例),但不对其进行初始化。然后,我们编写一个 private
构造函数,确保没有其他类可以调用其默认构造函数(public
)来创建对象。
最后,我们编写了一个 static
方法来检查 Singleton.java
类的实例,如果它是 null
,它只创建这个类的实例。在 Test.java
类中,我们可以通过创建不同的对象来确认,以确保每次只创建和调用一个实例。
使用早期初始化方法的 Java 单例类
示例代码(Singleton.java
):
class Singleton {
private static final Singleton object = new Singleton();
public String message;
private Singleton() {
message = "Hi I live in the Singleton class";
}
public static Singleton getInstance() {
return object;
}
}
示例代码(Test.java
):
public class Test {
public static void main(String args[]) {
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
Singleton obj3 = Singleton.getInstance();
System.out.println("Hashcode of obj1 is " + obj1.hashCode());
System.out.println("Hashcode of obj2 is " + obj2.hashCode());
System.out.println("Hashcode of obj3 is " + obj3.hashCode());
if (obj1 == obj2 && obj2 == obj3) {
System.out.println("Three instances reference to the same memory location");
} else {
System.out.println("All are not referencing to the same memory location");
}
}
}
输出:
Hashcode of obj1 is 1490180672
Hashcode of obj2 is 1490180672
Hashcode of obj3 is 1490180672
Three instances reference to the same memory location
在 Singleton.java
类中,我们创建该类的 private static final
实例并对其进行初始化。然后,我们编写一个 private
构造函数和一个静态方法来返回这个类的实例。
请记住,Signleton.java
类实例将在加载时创建。我们还可以将类的实例设置为 public static final
而不是 private static final
,以直接访问该类。
此外,我们有相同的 Test.java
类,它打印并确保每次只调用一个实例。