當前位置:生活全書館 >

IT科技

> resolve java

resolve java

<link rel="stylesheet" href="https://js.how234.com/third-party/SyntaxHighlighter/shCoreDefault.css" type="text/css" /><script type="text/javascript" src="https://js.how234.com/third-party/SyntaxHighlighter/shCore.js"></script><script type="text/javascript"> SyntaxHighlighter.all(); </script>

java resolve是什麼?讓我們一起來了解一下吧!

原理:

反序列化時,首先獲取序列化的類 : desc( 可理解為單例類的class類,但它和JVM載入到記憶體中的單例class類有不同)因為如果我們的單例類在構造方法中通過例項不為空則丟擲異常防止了反射破壞單例,那單例類是不允許再例項化的。而desc類卻依然可以例項化。(當我們反序列化一個物件時,永遠不會呼叫其類的建構函式,反序列化後的例項變數與序列化之前的例項變數相同,類變數與當前的類變數相同,如果反序列化時類未被載入則類變數為預設值。)

判斷物件是否能例項化。可以則進行例項化,至此單例類進行了第一次例項化,物件名為obj。第一次例項化完成後,通過反射尋找該單例類中的readResolve()方法,沒有則直接返回obj物件。有定義readResolve()方法,desc通過invokeReadResolve(Object obj)方法呼叫readResolve()方法獲取單例物件instance,將他賦值給rep,如果單例物件之前已經被例項化過,那麼rep就會指向之前例項化的單例物件。如果我們之前沒有例項化單例物件,則rep會指向null。

rep與obj進行比較,由於obj是反射獲取的物件,當然與rep不等,於是將rep的值instance賦值給obj,將obj返回,返回物件instance也就保證了單例。

java resolve

java resolve是從序列化中恢復一個單例物件會破壞單例模式,解決方法是新增readResolve() :通過反序列化readObject()方法獲取物件時會去尋找readResolve()方法,如果該方法不存在則直接返回新物件,如果該方法存在則按該方法的內容返回物件,以確保如果我們之前例項化了單例物件,就返回該物件。如果我們之前沒有例項化單例物件,則會返回null。

實戰演練,具體步驟如下所示:

package com.singleton; import java.io.ObjectStreamException;import java.io.Serializable; /** * 懶漢單例設計模式案例 */public class SingletonDemo implements Serializable {    /** * 懶載入 */private static SingletonDemo instance;     /**     * 私有構造器     */private SingletonDemo() {// 防止通過反射例項物件而跳過getInstance()方法if (instance != null) {throw new RuntimeException("Object has been Instance !!!");}} /** * 呼叫方法才載入類,資源利用率高了,但要保證執行緒安全 */public static synchronized SingletonDemo getInstance() {if (instance == null) {instance = new SingletonDemo();}return instance;} /** * 提供readResolve()方法 * 當JVM反序列化恢復一個新物件時,系統會自動呼叫readResolve()方法返回指定好的物件 * 從而保證系統通過反序列化機制不會產生多的Java物件 * * @return 單例物件 * @throws ObjectStreamException 異常 */private Object readResolve() throws ObjectStreamException {return instance;}}package com.singleton; import org.junit.Test; import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream; /** * 單例測試類 */public class SingletonTest { /** * 測試方法 */@Testpublic void test() throws Exception {// 獲取instance物件SingletonDemo instance = SingletonDemo.getInstance(); // 獲取檔案輸出流FileOutputStream fileOutputStream = new FileOutputStream("E:Test.txt");// 獲取物件輸出流ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); // 輸出物件objectOutputStream.writeObject(instance); // 關閉資源objectOutputStream.close();fileOutputStream.close(); // 獲取物件輸入流ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("E:Test.txt")); // 讀取物件Object object = objectInputStream.readObject(); // 判斷兩個物件是否相等,返回true/falseSystem.out.println(instance == object);} }

標籤: resolve java
  • 文章版權屬於文章作者所有,轉載請註明 https://shqsg.com/dianzi/8xqkek.html