static vs Singleton,静态类vs单例模式之争

https://stackoverflow.com/questions/519520/difference-between-static-class-and-singleton-pattern?answertab=modifieddesc#tab-top

实现接口,必须单例模式, only Singleton can implement interface

可以通过单例类来实现接口,但不能通过类的静态方法或者在某些语言(如C#)中的静态类来实现接口。这是因为接口是一种契约,它定义了一组方法的签名,而这些方法需要由实现接口的类的实例来实现。静态方法不属于任何实例,因此不能用来实现接口。
下面是一个Java的例子,展示了如何通过单例类来实现接口

interface MyInterface {
    void doSomething();
}

class Singleton implements MyInterface {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {	// 线程安全
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    @Override
    public void doSomething() {
        System.out.println("Doing something...");
    }
}

在这个例子中,Singleton类实现了MyInterface接口,并且我们通过getInstance方法来获取Singleton的实例。这个实例可以调用doSomething方法,因为它是MyInterface接口的一部分。 然而,如果我们试图通过静态方法来实现接口,就会遇到问题。例如,下面的代码是无效的:

interface MyInterface {
    void doSomething();
}

class MyClass {
    public static void doSomething() {
        System.out.println("Doing something...");
    }
}

在这个例子中,MyClass的静态方法doSomething并没有实现MyInterface接口。这是因为静态方法不属于任何实例,而接口需要由实例来实现。因此,我们不能通过静态方法来实现接口。

java的GC内存回收

单例模式仅在需要使用的地方才开始初始化
使用单例模式,每次都得先获取实例:

Singleton myS = Singleton.getInstance();
myS.doSomething();

静态类从一开始就预分配在内存中

Singleton.doSomething();

代码写起来更短了
建议方法很少、占用内存少时,才使用静态类,否则都使用单例模式
比如private byte[] cache_GB,这种要存几个GB的变量,用单例模式,就能在不使用时交给GC销毁。

安卓的context变成无效引用

public class MainActivity extends AppCompatActivity {
    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 必须先于binding初始化
        SharedPreferences.getInstance(this);

但若安卓把mainActivity的内存释放了,此时this就是个NullReference的无效引用,导致app直接崩溃

this持有一个对MainActivity的引用。如果MainActivity被销毁,这个引用就会变得无效。为了避免这种情况,您应该确保SecurePreferences类不持有任何对Activity的引用,或者在Activity被销毁时正确地清理这些引用。

解决办法:SharedPreferences.getInstance(getApplicationContext());
ApplicationContext在应用程序的整个生命周期中都存在,只有当应用程序被杀死时,它才会被销毁。

MainActivity何时销毁

在Android中,MainActivity或任何其他Activity可能会在以下情况下被销毁:

  • 当用户按下返回键或者调用finish()方法时,系统会销毁当前Activity。
  • 当系统内存不足,需要释放一些资源时,系统可能会销毁处于后台的Activity。
  • 当用户通过任务管理器关闭应用程序时,系统会销毁所有的Activity。
  • 当Activity的onDestroy()方法被调用时,Activity会被销毁。这通常发生在Activity生命周期结束时。
  • 当设备的屏幕方向改变(从竖屏变为横屏,或者反过来),并且Activity没有处理屏幕方向改变的事件时,系统会销毁并重新创建Activity。

请注意,即使Activity被销毁,应用程序进程可能仍然存在,除非系统需要释放资源,或者用户通过任务管理器关闭应用程序。

二者原本都不是线程安全

如果多线程同时获取实例,则二者都无法保证线程安全。在java中则需要synchronized关键字

posted @ 2024-06-05 12:00  Nolca  阅读(5)  评论(0编辑  收藏  举报