您的位置:首页 > Web前端

Effective Java 2.3——用私有构造器或者枚举类型强化Singleton属性

2017-04-12 13:58 513 查看

第三条:用私有构造器或者枚举类型强化Singleton属性

关于singleton我们在第一条的时候就有所涉及到了,当时是在讲静态工厂的其中一个优点:可以不重复创建多个无用的对象。在这里我们再展开说明一下Singleton属性。

Singleton指仅被实例化一次的类。Singleton通常被用来代表那些本质上唯一的系统组件。

实现SingleTon的几种方法如下:

公有成员是静态final域:

public class Main {
public static void main(String args[]) {
A a1 = A.a;
A a2 = A.a;
System.out.println(a1==a2);
}

}
class A
{
public static final A a = new A();;
private A(){

};
}


输出为:true

代码也不长,大家可以自己在ide上跑一下。根据输出的结果可以很好的说明a1和a2是同一个对象。

书中的原话:私有构造器仅被调用一次,用来实例化公有的静态final域A.a。由于缺少公有的或者受保护的构造器,所以保证了A的全局唯一性:一旦A被实例化,只会存在一个A的实例。

下面是第二种方法:

公有成员是静态工厂

public class Main {
public static void main(String args[]) {
A a1 = A.getInstance();
A a2 = A.getInstance();
System.out.println(a1==a2);
}

}
class A
{
private static final A a = new A();;
private A(){

};
public static A getInstance()
{
return a;
}
}


输出结果:true

上面的代码大家应该非常熟悉,就是我们在第一条的时候学习的静态工厂模式。没看过我之前的博文的可以去看看呦~静态工厂

使用静态工厂的时候要注意序列化的问题。因为很有可能会在每次反序列化的时候产生一个实例。

第三种方法:

枚举方式

public class Main {
public static void main(String args[]) {
A a1 = A.a;
A a2 = A.a;
System.out.println(a1==a2);
}

}
enum A
{
a;
}


输出:true

书中将此推崇为实现Singleton的最佳方法,由于枚举方式简洁,无偿提供了序列化机制,绝对防止多次序列化即使是在面临复杂的序列化或者反射攻击的时候。

对于枚举类型还不熟悉的童鞋们可以看看我下面的代码:

public class Main {
public static void main(String args[]) {
System.out.println(Color.RED.getColor());
System.out.println(Color.Green.getIndex());
System.out.println(Color.Green.getClass());
}

}
enum Color
{
RED(1,"red"),Green(2,"green");
int index;
String color;
Color(int index,String color)
{
this.index = index;
this.color = color;
}
int getIndex()
{
return index;
}
String getColor()
{
return color;
}
}


输出:

red

2

class Color

其实大家能够发现枚举跟类差不了太多,getClass()输出显示的还是class Color呢!只是枚举把它里面的变量都默认指定是public static final了,而且枚举类型里面的构造函数只能是private的,且默认也是。所以说虽然我上面的构造函数没有写private,其实就是private属性而不是我们平时类的缺省值(default)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java singleton
相关文章推荐