java resolve是什么?讓我們一起來了解一下吧!
原理:
反序列化時(shí),首先獲取序列化的類 : desc( 可理解為單例類的class類,但它和JVM加載到內(nèi)存中的單例class類有不同)因?yàn)槿绻覀兊膯卫愒跇?gòu)造方法中通過實(shí)例不為空則拋出異常防止了反射破壞單例,那單例類是不允許再實(shí)例化的。而desc類卻依然可以實(shí)例化。(當(dāng)我們反序列化一個(gè)對(duì)象時(shí),永遠(yuǎn)不會(huì)調(diào)用其類的構(gòu)造函數(shù),反序列化后的實(shí)例變量與序列化之前的實(shí)例變量相同,類變量與當(dāng)前的類變量相同,如果反序列化時(shí)類未被加載則類變量為默認(rèn)值。)
判斷對(duì)象是否能實(shí)例化??梢詣t進(jìn)行實(shí)例化,至此單例類進(jìn)行了第一次實(shí)例化,對(duì)象名為obj。第一次實(shí)例化完成后,通過反射尋找該單例類中的readResolve()方法,沒有則直接返回obj對(duì)象。有定義readResolve()方法,desc通過invokeReadResolve(Object obj)方法調(diào)用readResolve()方法獲取單例對(duì)象instance,將他賦值給rep,如果單例對(duì)象之前已經(jīng)被實(shí)例化過,那么rep就會(huì)指向之前實(shí)例化的單例對(duì)象。如果我們之前沒有實(shí)例化單例對(duì)象,則rep會(huì)指向null。
rep與obj進(jìn)行比較,由于obj是反射獲取的對(duì)象,當(dāng)然與rep不等,于是將rep的值instance賦值給obj,將obj返回,返回對(duì)象instance也就保證了單例。
java resolve是從序列化中恢復(fù)一個(gè)單例對(duì)象會(huì)破壞單例模式,解決方法是添加readResolve() :通過反序列化readObject()方法獲取對(duì)象時(shí)會(huì)去尋找readResolve()方法,如果該方法不存在則直接返回新對(duì)象,如果該方法存在則按該方法的內(nèi)容返回對(duì)象,以確保如果我們之前實(shí)例化了單例對(duì)象,就返回該對(duì)象。如果我們之前沒有實(shí)例化單例對(duì)象,則會(huì)返回null。
實(shí)戰(zhàn)演練,具體步驟如下所示:
package?com.singleton; ? import?java.io.ObjectStreamException; import?java.io.Serializable; ? /** ?*?懶漢單例設(shè)計(jì)模式案例 ?*/ public?class?SingletonDemo?implements?Serializable?{ ???? /** ?*?懶加載 ?*/ private?static?SingletonDemo?instance; ? ????/** ?????*?私有構(gòu)造器 ?????*/ private?SingletonDemo()?{ //?防止通過反射實(shí)例對(duì)象而跳過getInstance()方法 if?(instance?!=?null)?{ throw?new?RuntimeException("Object?has?been?Instance??。?!"); } } ? /** ?*?調(diào)用方法才加載類,資源利用率高了,但要保證線程安全 ?*/ public?static?synchronized?SingletonDemo?getInstance()?{ if?(instance?==?null)?{ instance?=?new?SingletonDemo(); } return?instance; } ? /** ?*?提供readResolve()方法 ?*?當(dāng)JVM反序列化恢復(fù)一個(gè)新對(duì)象時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)用readResolve()方法返回指定好的對(duì)象 ?*?從而保證系統(tǒng)通過反序列化機(jī)制不會(huì)產(chǎn)生多的Java對(duì)象 ?* ?*?@return?單例對(duì)象 ?*?@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; ? /** ?*?單例測(cè)試類 ?*/ public?class?SingletonTest?{ ? /** ?*?測(cè)試方法 ?*/ @Test public?void?test()?throws?Exception?{ //?獲取instance對(duì)象 SingletonDemo?instance?=?SingletonDemo.getInstance(); ? //?獲取文件輸出流 FileOutputStream?fileOutputStream?=?new?FileOutputStream("E:\\Test.txt"); //?獲取對(duì)象輸出流 ObjectOutputStream?objectOutputStream?=?new?ObjectOutputStream(fileOutputStream); ? //?輸出對(duì)象 objectOutputStream.writeObject(instance); ? //?關(guān)閉資源 objectOutputStream.close(); fileOutputStream.close(); ? //?獲取對(duì)象輸入流 ObjectInputStream?objectInputStream?=?new?ObjectInputStream(new?FileInputStream("E:\\Test.txt")); ? //?讀取對(duì)象 Object?object?=?objectInputStream.readObject(); ? //?判斷兩個(gè)對(duì)象是否相等,返回true/false System.out.println(instance?==?object); } ? }
以上就是小編今天的分享了,希望可以幫助到大家。