Javaの単一の例のモードの実現方式とその長所と短所――単一の例のモードはまたこのように実現することができる。
一例モードの三種類の初期化方法とその長所と短所
一、共通の一例モードの実現方式
単一の例モード:名前の通りに1つのクラスが1つのインスタンスだけであることを保証し、自己の実装(プライベート構造方法)を行い、システム全体にこの例を提供する。 一般的な一例モードは三つのモードがあります。怠け者式の一例、餓漢式の一例、静的な内部類の一例(登録式の一例、holderの一例ともいいます。)
1.餓漢式の一例
実現方式:
2.怠け者式の一例(満腹漢式の一例ともいう)
実現方式の同期方法:
3.静的内部類の一例
実現方式:
4.反射防止侵入方法
_; Java反射機構とは、動作状態において、どのクラスについてもこのクラスのすべての属性と方法を知ることができるというものである。また、いずれのオブジェクトに対しても、その任意の方法を呼び出すことができる。 単一例モードは、通常の場合、get Instance()によってのみインスタンスを作成することができます。しかし、反射によって、prvate方法を直接呼び出してインスタンスを作成することもでき、すなわち、複数のプライベート構造方法を起動して、反射侵入の問題を発生することができる。反射侵入を回避する方法の考え方は、一例のような構造法を複数回にわたって呼び出さないようにすることで、私有構造法とget Instance方法に変更することによって実現され、以下の実装は、内部静的なタイプのパターンを例として挙げられる。
上で紹介した3つの例示的な実現方式は、比較的一般的な方法であり、以下ではより簡単で効率的な単一の例のモードを紹介します。実施の形態一:構造方法におけるオブジェクトの実用化エニュメレーションの一例には、プログレッシブとスレッドセキュリティの保証があり、JVMはエニュメレーション類の構造方法が絶対に一回だけ呼び出されることを保証しますので、対象インスタンスの一意性を保証します。 エニュメレーションENUMタイプでは、反射呼び出しは禁止されており、反射侵入は生まれつき避けられています。
一、共通の一例モードの実現方式
単一の例モード:名前の通りに1つのクラスが1つのインスタンスだけであることを保証し、自己の実装(プライベート構造方法)を行い、システム全体にこの例を提供する。 一般的な一例モードは三つのモードがあります。怠け者式の一例、餓漢式の一例、静的な内部類の一例(登録式の一例、holderの一例ともいいます。)
1.餓漢式の一例
実現方式:
public class Singleton {
private static final Singleton SINGLETON = new Singleton();
private Singleton{}; //
public static Singleton getInstance() {
return SINGLETON;
}
}
メリット:ロックがないと、実行効率が高くなります。欠点:クラスがロードする時初期化して、メモリを浪費します。2.怠け者式の一例(満腹漢式の一例ともいう)
実現方式の同期方法:
public class Singleton {
private static Singleton singleton;
private Singleton{}; //
public synchronized static Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
実現方式の二同期コードブロック(ダブルチェックロック方式、方式より良い):public class Singleton {
private static Singleton singleton;
private Singleton{}; //
public static Singleton getInstance() {
if (singleton == null) {
synchronized(Singleton.class) {
if(singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
利点:初めての呼び出しで初期化し、メモリの無駄を避ける。欠点:ロックしなければならないsynchronizedは単一の例を保証することができません。すなわちスレッド同期を考慮しなければならない。3.静的内部類の一例
実現方式:
public class Singleton {
private static Singleton singleton;
private Singleton{}; //
public static Singleton getInstance() {
return Holeder.SINGLETON;
}
private static class Holder {
private final static Singleton SINGLETON = new Singleton();
}
}
内部クラスは外部クラスで呼び出されて初めてロードされ、SINGLETONの例を生成する。2)ロックは不要です短所:コードがちょっと複雑です。4.反射防止侵入方法
_; Java反射機構とは、動作状態において、どのクラスについてもこのクラスのすべての属性と方法を知ることができるというものである。また、いずれのオブジェクトに対しても、その任意の方法を呼び出すことができる。 単一例モードは、通常の場合、get Instance()によってのみインスタンスを作成することができます。しかし、反射によって、prvate方法を直接呼び出してインスタンスを作成することもでき、すなわち、複数のプライベート構造方法を起動して、反射侵入の問題を発生することができる。反射侵入を回避する方法の考え方は、一例のような構造法を複数回にわたって呼び出さないようにすることで、私有構造法とget Instance方法に変更することによって実現され、以下の実装は、内部静的なタイプのパターンを例として挙げられる。
public class Singleton {
private static boolean sFlag = true;
private static Singleton singleton;
private Singleton{
if (sFlag) {
sFlag = fase;
} else { //
throw new RuntimeException(" ");
}
}; //
public static Singleton getInstance() {
return Holeder.SINGLETON;
}
private static class Holder {
private final static Singleton SINGLETON = new Singleton();
}
}
二、高効率の一例モード実現——列挙タイプの一例モード上で紹介した3つの例示的な実現方式は、比較的一般的な方法であり、以下ではより簡単で効率的な単一の例のモードを紹介します。実施の形態一:構造方法におけるオブジェクトの実用化
//
public enum Singleton {
INSTANCE;
public Singleton getInstance() {
return INSTANCE;
}
public void method1() {
}
}
//
Singleton.INSTANCE.method1();
//
public class EnumSingleton {
private EnumSingleton(){}
public static EnumSingleton getInstance(){
return Singleton.INSTANCE.getInstance();
}
private enum Singleton{
INSTANCE;
private EnumSingleton singleton;
//JVM
Singleton(){
singleton = new EnumSingleton();
}
public EnumSingleton getInstance(){
return singleton;
}
}
}
//
EnumSingleton.getInstance().method1();
実施の形態2:列挙定数の値は、オブジェクトの例である。public class EnumSingleton {
private EnumSingleton(){}
public static EnumSingleton getInstance(){
return Singleton.INSTANCE.getInstance();
}
private enum Singleton{
//
INSTANCE(new EnumSingleton());
private EnumSingleton singleton;
//JVM
Singleton(EnumSingleton singleton){
this.singleton = singleton;
}
public EnumSingleton getInstance(){
return singleton;
}
}
}
//
EnumSingleton.getInstance().method1();
利点: