📜  Java单例模式和静态类的区别

📅  最后修改于: 2021-09-13 02:30:56             🧑  作者: Mango

单例模式属于创造型模式。顾名思义,创建型设计类型处理对象创建机制。基本上,为了简化这一点,创建模式向我们解释了以适合给定情况的方式创建对象。当我们需要确保特定类的只有一个对象被实例化时,就会使用单例设计模式。创建的单个实例负责协调整个应用程序的操作。

试图调用实例化为单例的对象的不同对象。

如果您查看上面的图示,您将看到不同的对象试图调用实例化为单例的对象。这个对象的单个实例负责调用下面的方法或事件。

单例模式指南如下:

好处:

  • 单例控制对资源的并发访问。
  • 它确保整个应用程序中只有一个处于受控状态的对象可用。

执行:

  • 确保该类只存在一个实例。
  • 通过将类的所有构造函数声明为私有来提供对该访问的全局实例,提供返回对实例的引用的静态方法,并且该实例存储为私有静态变量。

例子

Java
// Java Program to illsutrate Difference Between
// Singleton Pattern vs Static Class.
  
// Here illustrating Singleton Pattern
  
// Importing input output classes
import java.io.*;
  
// Class 1
// Helper class
class SingletonEagar {
  
    // Declaration and definition of variable occur
    // simultaneously
    //  Eager initialisation
    private static SingletonEagar instance
        = new SingletonEagar();
  
    // Private constructor of class 1
    private SingletonEagar() {}
  
    public static SingletonEagar getInstance()
    {
        return instance;
    }
}
  
// Class 2
// Helper Class
class Singleton {
  
    // Lazy  declaration and initialisation
    private static Singleton instance;
  
    // Private constructor of Class 2
    private Singleton() {}
  
    public static Singleton getInstance()
    {
  
        // Condition check
        // When instance is null
        // a new object of Singleton class is created
        if (instance == null) {
            instance = new Singleton();
        }
  
        return instance;
    }
}
  
// Class 3
// Helper class
class SingletonSynchronizedMethod {
  
    private static SingletonSynchronizedMethod instance;
  
    // Private constructor of Class 3
    private SingletonSynchronizedMethod() {}
  
    public static synchronized SingletonSynchronizedMethod
    getInstance()
    {
  
        // Condition check
        // When instance is null
        // a new object of Singleton class is created
        if (instance == null) {
            instance = new SingletonSynchronizedMethod();
        }
  
        return instance;
    }
}
  
// Class 4
// Helper class
class SingletonSynchronized {
  
    private static SingletonSynchronized instance;
  
    // Private constructor of Class 4
    private SingletonSynchronized() {}
  
    public static SingletonSynchronized getInstance()
    {
  
        // Again, condition check
        if (instance == null) {
  
            // synchronized block
            synchronized (SingletonSynchronized.class)
            {
  
                if (instance == null) {
                    instance = new SingletonSynchronized();
                }
            }
        }
        return instance;
    }
}
  
// Class 5
// Main class (SingletonExample)
public class GFG {
  
    // Main driver method
    public static void main(String[] args)
    {
  
        // Creating instanc in main() method of class 1
        SingletonEagar instance1
            = SingletonEagar.getInstance();
  
        // Display message only
        System.out.println(
            instance1
            + " : Singleton Eager initialisation ");
  
        // Creating instanc in main() method of class 2
        Singleton instance2 = Singleton.getInstance();
  
        // Display message only
        System.out.println(
            instance2
            + " : Singleton Lazy initialisation ");
  
        // Creating instanc in main() method of class 4
        SingletonSynchronized instance3
            = SingletonSynchronized.getInstance();
  
        // Display message only
        System.out.println(instance3
                           + " : Synchronized Singleton");
    }
}


Java
// Java Program to illsutrate Difference Between
// Singleton Pattern vs Static Class.
  
// Here illustrating Static Class
  
// Importing input output classes
import java.io.*;
  
// Class 1
// Helper Class
class GFG_Outer {
  
    // Custom input integer value
    static int x = 20;
  
    public static void display() { System.out.println(x); }
    // Class 2
    // Static inner class
  
    // Can access all static variables of outer class
    // Can't access non-static members
    static class GFG_Inner {
  
        GFG_Inner()
        {
  
            // Display message
            System.out.println(
                "This is Inner Class Constructor...");
  
            // Print the value of x from inside class thrown
            // on console
            System.out.println(
                "Value of \"x\" from inside Inner Class is : "
                + x);
        }
    }
  
    // Main driver method
    public static void main(String[] args)
    {
  
        // Printing value of x in the main() method
        System.out.println(GFG_Outer.x);
  
        // Calling display() method from class 1
        GFG_Outer.display();
  
        // static inner class object which is as follows:
        // OuterClass.InnerClass variable = new
        // OuterClass.InnerClass();
        GFG_Outer.GFG_Inner object
            = new GFG_Outer.GFG_Inner();
    }
}


输出

SingletonEagar@2f4d3709 : Singleton Eager initialisation 
Singleton@1d81eb93 : Singleton Lazy initialisation 
SingletonSynchronized@34a245ab : Synchronized Singleton

静态类

静态嵌套类是声明为静态的嵌套类。在Java,静态类是一种将类组合在一起的便捷方式。 Java不允许您创建顶级静态类;仅嵌套(内部)类。这就是为什么静态类也称为静态内部类或静态嵌套类的原因。

静态类的准则如下:

好处:

  • 通过使其成为静态,可以在类内部定义相关或帮助类。
  • 它可以通过对象引用访问封闭类的私有成员。
  • 静态类为嵌套类提供了一个很好的命名空间。
  • 如果封闭类被更新,我们也可以在同一位置更新静态类。
  • 在 JVM 中,Classloader 仅在第一次使用时加载静态类,而不是在加载其封闭类时。

执行:

  • 静态类只能是内部类或嵌套类。
  • 静态类可以像任何其他静态成员一样使用任何类型的访问修饰符(私有、受保护、公共或默认)。
  • 静态类只能访问其封闭类的静态成员。
  • 静态类只能通过其封闭类的对象与非静态成员进行交互,因为它不能直接访问其封闭类的非静态成员。

例子

Java

// Java Program to illsutrate Difference Between
// Singleton Pattern vs Static Class.
  
// Here illustrating Static Class
  
// Importing input output classes
import java.io.*;
  
// Class 1
// Helper Class
class GFG_Outer {
  
    // Custom input integer value
    static int x = 20;
  
    public static void display() { System.out.println(x); }
    // Class 2
    // Static inner class
  
    // Can access all static variables of outer class
    // Can't access non-static members
    static class GFG_Inner {
  
        GFG_Inner()
        {
  
            // Display message
            System.out.println(
                "This is Inner Class Constructor...");
  
            // Print the value of x from inside class thrown
            // on console
            System.out.println(
                "Value of \"x\" from inside Inner Class is : "
                + x);
        }
    }
  
    // Main driver method
    public static void main(String[] args)
    {
  
        // Printing value of x in the main() method
        System.out.println(GFG_Outer.x);
  
        // Calling display() method from class 1
        GFG_Outer.display();
  
        // static inner class object which is as follows:
        // OuterClass.InnerClass variable = new
        // OuterClass.InnerClass();
        GFG_Outer.GFG_Inner object
            = new GFG_Outer.GFG_Inner();
    }
}
输出
20
20
This is Inner Class Constructor...
Value of "x" from inside Inner Class is : 20
Singleton Pattern Static Class
Singleton is a design pattern. Static classes are basically a way of grouping classes together in Java.
Memory is allocated once the object is created. Memory is allocated immediately after any of the class members is accessed.
Singleton implementation can either have static members or instance members. Static classes can contain static members only.
It can implement any other interface or base class is required. It cannot implement the interface or any other base class.
Singleton classes can be used as a method parameter. Static class cannot be used as a method parameter. 
Singleton pattern uses Heap memory. Static classes use stack memory.
It works within the scope of Garbage Collector as it uses Heap memory. Out of scope for Garbage Collector as it uses stack memory.
It supports Dependency Injection (DI) implementation as Singleton follows OOPS concepts. It cannot implement Dependency Injection (DI) as DI is Interface-driven.
Singleton is an architectural pattern and not a language feature. Static is a language feature and not an Architectural pattern.
Disposal of objects is possible. It cannot dispose of the static class as there is no instance created.