當前位置:生活全書館 >

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);} }

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