単例類パターンの破壊防止を徹底的に理解する
優鋭授業の学習共有では,単例属性を破壊する3つの主要な方法とそれをどのように防止するかを検討した.みんなに参考にして勉強します.
必要に応じて、アプリケーションで単一の設計モードを使用することに慣れています.単一の設計モードでは、インスタンスを作成してアプリケーション全体にアクセスするしかないことはよく知られています.しかし、場合によっては、単一の動作を破壊します.3つの主な概念では,JavaにおけるSingletonクラスのsingleton属性を破ることができる.この文章では、それを破壊する方法と防止する方法について議論します.これはSingletonクラスとSingletonTestクラスの例です.单例
Singleton.Java
SingletonTest.java
これは出力です.objectOneとobjectTwoと同じhashcodeを持っていることがわかります.
今、私たちはこのモードを破ります.まず、Java反射を使用します.
はんしゃ
Java Reflectionは、実行時にメソッド、クラス、インタフェースの動作をチェックまたは変更するためのAPIです.Reflection APIを使用すると、Singletonクラスに複数のオブジェクトを作成できます.次の例を考慮します:ReflectionSingleton.java
この例では,反射がJava反射で単一例モードを破る方法を示した.次のように2つのハッシュコードが得られます.単例モードで突破しました.
モノリシックモード反射防止
反射APIにおけるSingletonモードを防止する方法は数多くあるが、最良の解決策の1つは、インスタンスが既に存在する場合、コンストラクション関数でランタイム異常が発生することである.この場合、2番目のインスタンスを作成することはできません.
逆シーケンス化
シーケンス化では、バイトストリームのオブジェクトをファイルに保存したり、ネットワークを介して送信したりすることができます.Singletonクラスをシーケンス化してから、オブジェクトを再度逆シーケンス化すると、新しいインスタンスが作成され、逆シーケンス化はSingletonモードを破壊します.
次のコードは、逆シーケンス化によって単一の逆モードがどのように中断されるかを説明するために使用されます.SingletonクラスのSerializableインタフェースを実装します.
DeserializationSingleton.Java
出力は次の通りです.hashcodesが2つ見えます.
シングル・スキーマの逆シーケンス化の防止
この問題を克服するために,SingletonクラスのreadResolve()メソッドを上書きし,同じSingletonインスタンスを返す必要がある.Singleton.javaを更新するには、次の方法を使用します.
次に、上記のDeserializationDemoクラスを実行し、出力を表示します.
クローン作成
[クローン](Clone)メソッドを使用すると、元のオブジェクトのコピーを作成できます.モノリシックモードでクローンを適用すると、これは同じことです.2つのインスタンスが作成されます.1つのインスタンスと別のインスタンスです.この場合,次のコードに示すようにSingleton原理を打ち破る.
「クローニング可能」インターフェースを実装し、上記Singletonカテゴリにcloneメソッドを上書き
Singleton.java
次に、クローンをテストして、単一の例を破ります.
CloningSingleton.java
これは出力です.
上記の出力を見ると、2つのインスタンスは異なるhashcodesを有する.これは、これらのインスタンスが異なることを意味します.
シングル・スキーマのクローン作成の防止
上のコードでは、Singletonの原理、すなわち.eは2つのインスタンスを作成した.上記の問題を克服するためには、clone()メソッドを実装/上書きし、クローンメソッドから異常CloneNotSupportedExceptionを放出する必要があります.Singletonのクローンオブジェクトを作成しようとすると、次のコードに示すように例外が放出されます.
これでloningSingletonクラスを実行できます.個々のオブジェクトのクローンオブジェクトを作成すると、CloneNotSupportedExceptionが放出されます.
文章はここまで书いて、もし足りないところがあれば、补充コメントを歓迎します.この文章があなたに役に立つことを望んでいます!
必要に応じて、アプリケーションで単一の設計モードを使用することに慣れています.単一の設計モードでは、インスタンスを作成してアプリケーション全体にアクセスするしかないことはよく知られています.しかし、場合によっては、単一の動作を破壊します.3つの主な概念では,JavaにおけるSingletonクラスのsingleton属性を破ることができる.この文章では、それを破壊する方法と防止する方法について議論します.これはSingletonクラスとSingletonTestクラスの例です.单例
Singleton.Java
package demo1;
public final class Singleton {
private static volatile Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
SingletonTest.java
package demo1;
public class SingletonTest {
public static void main(String[] args) {
Singleton object1 = Singleton.getInstance();
Singleton object2 = Singleton.getInstance();
System.out.println("Hashcode of Object 1 - " + object1.hashCode());
System.out.println("Hashcode of Object 2 - " + object2.hashCode());
}
}
これは出力です.objectOneとobjectTwoと同じhashcodeを持っていることがわかります.
Hashcode of Object 1 - 1836019240
Hashcode of Object 2 - 1836019240
今、私たちはこのモードを破ります.まず、Java反射を使用します.
はんしゃ
Java Reflectionは、実行時にメソッド、クラス、インタフェースの動作をチェックまたは変更するためのAPIです.Reflection APIを使用すると、Singletonクラスに複数のオブジェクトを作成できます.次の例を考慮します:ReflectionSingleton.java
package demo1;
import java.lang.reflect.Constructor;
public class ReflectionSingleton {
public static void main(String[] args) {
Singleton objOne = Singleton.getInstance();
Singleton objTwo = null;
try {
Constructor constructor = Singleton.class.getDeclaredConstructor();
constructor.setAccessible(true);
objTwo = (Singleton) constructor.newInstance();
} catch (Exception ex) {
System.out.println(ex);
}
System.out.println("Hashcode of Object 1 - "+objOne.hashCode());
System.out.println("Hashcode of Object 2 - "+objTwo.hashCode());
}
}
この例では,反射がJava反射で単一例モードを破る方法を示した.次のように2つのハッシュコードが得られます.単例モードで突破しました.
モノリシックモード反射防止
反射APIにおけるSingletonモードを防止する方法は数多くあるが、最良の解決策の1つは、インスタンスが既に存在する場合、コンストラクション関数でランタイム異常が発生することである.この場合、2番目のインスタンスを作成することはできません.
逆シーケンス化
シーケンス化では、バイトストリームのオブジェクトをファイルに保存したり、ネットワークを介して送信したりすることができます.Singletonクラスをシーケンス化してから、オブジェクトを再度逆シーケンス化すると、新しいインスタンスが作成され、逆シーケンス化はSingletonモードを破壊します.
次のコードは、逆シーケンス化によって単一の逆モードがどのように中断されるかを説明するために使用されます.SingletonクラスのSerializableインタフェースを実装します.
DeserializationSingleton.Java
package demo1;
import java.io.*;
public class DeserializationSingleton {
public static void main(String[] args) throws Exception {
Singleton instanceOne = Singleton.getInstance();
ObjectOutput out = new ObjectOutputStream(new FileOutputStream("file.text"));
out.writeObject(instanceOne);
out.close();
ObjectInput in = new ObjectInputStream(new FileInputStream("file.text"));
Singleton instanceTwo = (Singleton) in.readObject();
in.close();
System.out.println("hashCode of instance 1 is - " + instanceOne.hashCode());
System.out.println("hashCode of instance 2 is - " + instanceTwo.hashCode());
}
}
出力は次の通りです.hashcodesが2つ見えます.
hashCode of instance 1 is - 2125039532
hashCode of instance 2 is - 381259350
シングル・スキーマの逆シーケンス化の防止
この問題を克服するために,SingletonクラスのreadResolve()メソッドを上書きし,同じSingletonインスタンスを返す必要がある.Singleton.javaを更新するには、次の方法を使用します.
protected Object readResolve() {
return instance;
}
次に、上記のDeserializationDemoクラスを実行し、出力を表示します.
hashCode of instance 1 is - 2125039532
hashCode of instance 2 is - 2125039532
クローン作成
[クローン](Clone)メソッドを使用すると、元のオブジェクトのコピーを作成できます.モノリシックモードでクローンを適用すると、これは同じことです.2つのインスタンスが作成されます.1つのインスタンスと別のインスタンスです.この場合,次のコードに示すようにSingleton原理を打ち破る.
「クローニング可能」インターフェースを実装し、上記Singletonカテゴリにcloneメソッドを上書き
Singleton.java
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
次に、クローンをテストして、単一の例を破ります.
CloningSingleton.java
public class CloningSingleton {
public static void main(String[] args) throws CloneNotSupportedException, Exception {
Singleton instanceOne = Singleton.getInstance();
Singleton instanceTwo = (Singleton) instanceOne.clone();
System.out.println("hashCode of instance 1 - " + instanceOne.hashCode());
System.out.println("hashCode of instance 2 - " + instanceTwo.hashCode());
}
}
これは出力です.
hashCode of instance 1 - 1836019240
hashCode of instance 2 - 325040804
上記の出力を見ると、2つのインスタンスは異なるhashcodesを有する.これは、これらのインスタンスが異なることを意味します.
シングル・スキーマのクローン作成の防止
上のコードでは、Singletonの原理、すなわち.eは2つのインスタンスを作成した.上記の問題を克服するためには、clone()メソッドを実装/上書きし、クローンメソッドから異常CloneNotSupportedExceptionを放出する必要があります.Singletonのクローンオブジェクトを作成しようとすると、次のコードに示すように例外が放出されます.
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
これでloningSingletonクラスを実行できます.個々のオブジェクトのクローンオブジェクトを作成すると、CloneNotSupportedExceptionが放出されます.
文章はここまで书いて、もし足りないところがあれば、补充コメントを歓迎します.この文章があなたに役に立つことを望んでいます!