本文介绍了为什么私有静态字段=新的Singleton在Java中不是懒惰的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了很多关于Singleton的文章,其中大多数作者都说Java中的Singleton变体:

I read a lot of articles about Singleton, in most of which authors said that this variation of Singleton in Java:

public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton() {}
    public static Singleton getInstance() {
        return instance;
    }
}

NOT LAZY EAGER然后)。

但我不明白为什么, Singleton() constuctor将仅在 Singleton 类初始化时调用。我知道几个原因,可以触发类初始化:

But I can't understand why, Singleton() constuctor will be invoked only on Singleton class initialization. I know several reasons, which can trigger class initialization:


  1. 使用 new 和构造函数(但在这种情况下,构造函数是私有的。)

  2. 访问或设置静态字段(此处为私有)。

  3. 使用静态方法。

  4. 使用反射: Class.forName(Singleton)

  1. Using new with constructor (but in this case constructor is private).
  2. Accessing or setting up static field (here private).
  3. Using static method.
  4. With reflection: Class.forName("Singleton").

所以这里我们的对象只会在使用静态方法 getInstance()时创建(我仍然是 LAZY 初始化)和反射(但反射可以破坏很多单身人士的变化,除了 enum 可能)。

So here our object will be created only on using static method getInstance() (it is still LAZY initialization I guess) and with reflection (but reflection can ruin a lot of Singleton variations, except enum maybe).

也许我可以看不清楚的东西,请解释一下,我错在哪里?

Maybe I can't see something obvious, explain me please, where was I wrong?

推荐答案

基本上这是一个懒惰程度的问题。它是懒惰的,因为它不会在类初始化之前构造单例,但是它急切地认为可能是你想要在没有初始化单例的情况下使用类的情况。

Basically it's a matter of degrees of laziness. It's lazy in that it won't construct the singleton until the class is initialized, but it's eager in that there could be situations where you want to use the class without initializing the singleton itself.

例如:

public final class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }

    public static void sayHello() {
        System.out.println("Hello!");
    }
}

调用 Singleton.sayHello( )将实例化单例,即使我们不希望它......所以它不像它那样懒惰。

Calling Singleton.sayHello() will instantiate the singleton even if we don't want it to... so it's not as lazy as it could be.

你可以使用嵌套类型绕过这个:

You can get round this using a nested type:

public final class Singleton {
    private Singleton() {}

    public static Singleton getInstance() {
        return Holder.instance;
    }

    public static void sayHello() {
        System.out.println("Hello!");
    }

    private static class Holder {
        private static final Singleton instance = new Singleton();
    }
}

现在 Singleton.Holder 只能使用 getInstance 方法初始化。这是懒惰和线程安全的,没有锁定。

Now Singleton.Holder will only be initialized by using the getInstance method. It's lazy and thread-safe with no locking.

根据我的经验,通常单例类的静态方法是 getInstance 方法,在这种情况下它们是等价的(例如,假设您不使用反射以某种方式初始化类型)。

In my experience, usually a singleton class's only static method is the getInstance method, in which case they're equivalent (assuming you don't use reflection to initialize the type somehow, for example).

这篇关于为什么私有静态字段=新的Singleton在Java中不是懒惰的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 00:04