efficient in Java,Item 3 - What is an efficient way to implement a singleton pattern in Java?

Depending on the usage, there are several "correct" answers.

Since java5 the best way to do it is to use an enum:

public enumFoo {

INSTANCE;

}

The Right Way to Implement a Serializable Singletonpublic enumElvis {

INSTANCE;private final String[] favoriteSongs ={"Hound Dog", "Heartbreak Hotel"};public voidprintFavorites() {

System.out.println(Arrays.toString(favoriteSongs));

}

}

理解:JDK5之后,建议用用枚举类的方式实现单例的方式。

Pre java5, the most simple case is:

public final classFoo {private static final Foo INSTANCE = new Foo(); //加载Foo的时候对INSTANCE进行了实例化

privateFoo() {if (INSTANCE != null) {throw new IllegalStateException("Already instantiated");

}

}public staticFoo getInstance() {returnINSTANCE;

}

}

Let‘s go over the code. First, you want the class to be final. In this case, I‘ve used thefinalkeyword to let the users know it is final. Then you need to make the constructor private to prevent users to create their own Foo. Throwing an exception from the constructor prevents users to use reflection to create a second Foo. Then you create aprivate static final Foofield to hold the only instance, and apublic static Foo getInstance()method to return it. The Java specification makes sure that the constructor is only called when the class is first used.

When you have a very large object or heavy construction code AND also have other accessible static methods or fields that might be used before an instance is needed, then and only then you need to use lazy initialization.

You can use aprivate static classto load the instance. The code would then look like:

public final classFoo {private static classFooLoader {private static final Foo INSTANCE = newFoo();

}privateFoo() {if (FooLoader.INSTANCE != null) {throw new IllegalStateException("Already instantiated");

}

}public staticFoo getInstance() {return FooLoader.INSTANCE; //调用getInstance()方法时对FooLoader类进行了加载并实例化了INSTANCE

}

}

Since the lineprivate static final Foo INSTANCE = new Foo();is only executed when the class FooLoader is actually used, this takes care of the lazy instantiation, and is it guaranteed to be thread safe.

When you also want to be able to serialize your object you need to make sure that deserialization won‘t create a copy.

public final class Foo implementsSerializable {private static final long serialVersionUID = 1L;private static classFooLoader {private static final Foo INSTANCE = newFoo();

}privateFoo() {if (FooLoader.INSTANCE != null) {throw new IllegalStateException("Already instantiated");

}

}public staticFoo getInstance() {returnFooLoader.INSTANCE;

}

@SuppressWarnings("unused")privateFoo readResolve() {returnFooLoader.INSTANCE;

}

}

The methodreadResolve()will make sure the only instance will be returned, even when the object was serialized in a previous run of your program.

原文:http://www.cnblogs.com/Guoyutian/p/5077524.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值