正确实施初始化请求支持者习语 [英] Correct implementation of initialization-on-demand holder idiom

查看:156
本文介绍了正确实施初始化请求支持者习语的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个版本的Initialization-on-demand holder idiom:

I have got two versions of "Initialization-on-demand holder idiom":


  1. http://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom

  2. http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh

  1. http://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom
  2. http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh

上面的主要区别是第一个声明为 c> INSTANCE 为私人,但第二个宣称 INSTANCE public

The major difference between above is that the first one declared INSTANCE as private, but the second one declared INSTANCE as public.

请告诉我应该使用哪一个。

Please tell me which one should I use.

对不起,我没有发现使用 private public

Sorry, I have not found the difference between using private and public in my application:

public class Singleton {
    private int x;
    public int getX() {
        return x;
    }

    private Singleton () {}

    private static class LazyHolder {
        //both private and public works
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return LazyHolder.INSTANCE;
    }
}

我唯一要做的就是调用类似 Singleton.getInsance()。getX(),所以这两个版本都有效。
因此,我想知道使用它们的情况。

The only thing I do is to call something like Singleton.getInsance().getX(), so both versions works. Thus I want to know the situations for using them.

推荐答案

有几个事情要解释单身人士和初始化按需持有人成语。这里我们去:

There are several things to explain about singletons and the initialization-on-demand holder idiom. Here we go:

1)访问修饰符:

通常你不能访问字段和方法另一个课堂,如果他们是私人的。至少如果访问类在同一个包中,至少必须是私有的(没有修饰符)。所以执行它的正确方法是:

Normally you can't access fields and methods in another class if they are private. They must at least be package private (having no modifier, it is) if the accessing class is in the same package. So the correct way to implement it, would be:

public class Singleton {
    ...
    private static class LazyHolder {
        static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return LazyHolder.INSTANCE;
    }
}

但是, JLS 6.6.1 解释:


否则,如果成员或构造函数被声明为private,那么当且仅当发生在顶级类的主体中时才允许
(§7.6)
包含成员或构造函数的声明。

Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

这意味着,声明字段 INSTANCE 作为私人仍然允许从顶级类 Singleton 内的访问。但是编译器必须做一些技巧来解决私有修饰符:它插入包私有方法来获取和设置这样一个字段。

That means, declaring the field INSTANCE as private still allows the access from inside the top level class Singleton. But the compiler must do some tricks to get around the private modifier: It inserts package private methods for getting and setting such a field.

其实没关系,你放在哪个修饰符上如果它是公开的,它仍然不能从 Singleton 的其他类访问。但是...我认为包私人访问是最好的。使其公开没有意义。使私有化强制编译器做一些技巧。使其包私有反映您所拥有的:从另一个类访问课程成员。

In fact, it does not matter, which modifier you place on it. If it is public, it still cannot be accessed from other classes than Singleton. However ... I think the package private access is the best. Making it public does not makes sense. Making it private forces the compiler to do some tricks. Making it package private reflects what you have: Access to a class member from another class.

2)如何实现单例:

如果你想考虑序列化,单例实现将会有点困难。 Joshu Bloch在他的关于实施单身人士的有效Java一书中写了一个很大的部分。最后,他总结说,为了简单地使用一个枚举,因为Java枚举规范提供了单身人士需要的每个charecteristic。当然,这不再是成语了。

If you ever want to consider serialization, the singleton implementation will get a bit difficult. Joshu Bloch wrote a great section in his book "Effective Java" about implementing singletons. At the end, he concluded to simply use an enum for this, as the Java enum specification provides every charecteristic that is needed in regards to singletons. Of course, that does not use the idiom anymore.

3)考虑设计:

在大多数设计决策中单身人士不再有地方了。事实上,如果您必须将单例放入程序中,可能会显示设计问题。请记住:Singletons为某些数据或服务提供了一个全局访问机制。这不是OOP。

In most design decisions, singletons do not have their places anymore. In fact, it could indicate a design issue, if you must place a singleton into your program. Keep in mind: Singletons provide a global acess mechanism to some data or services. And this is not OOP.

这篇关于正确实施初始化请求支持者习语的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆