2016-03-09 15 views
6

अगर मैं एक Class वस्तु को क्रमानुसार (उदाहरण के लिए, HashMap.class), और फिर JVM का एक और उदाहरण में यह deserialize, यह पता चला है कि deserialized वर्ग एक वर्तमान में लोड करने के लिए समान होता है:जावा क्लास ऑब्जेक्ट्स को वर्तमान में लोड क्लास ऑब्जेक्ट्स को अपनी पहचान को संरक्षित करते समय कैसे कर सकता है?

import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.util.HashMap; 

final class DeserializationTest { 

    static String path = "/home/suseika/test.ser"; 
    static Class<HashMap> cls = HashMap.class; 

    public static void main(String[] args) throws Exception { 
     if (args[0].equals("serialize")) { 
      serialize(); 
     } else if (args[0].equals("deserialize")) { 
      final Object deserialized = deserialize(); 

      // The important line, prints "true" 
      System.out.println(deserialized == cls); 
     } 
    } 

    static Object deserialize() throws Exception { 
     ObjectInputStream in = new ObjectInputStream(new FileInputStream(path)); 
     return in.readObject(); 
    } 

    static void serialize() throws Exception { 
     FileOutputStream fileOut = new FileOutputStream(path); 
     ObjectOutputStream out = new ObjectOutputStream(fileOut); 
     out.writeObject(cls); 
     out.close(); 
     fileOut.close(); 
    } 
} 

जावा कैसे है इस मामले में वस्तुओं को deserialize करने में सक्षम है ताकि पहचान संरक्षित है? ClasswriteObject()/readObject()/readResolve() लागू करने के लिए प्रतीत नहीं होता है।

क्या यह व्यवहार एक विशेष कक्षा लोड करने/किसी विशेष क्लासलोडर का उपयोग करके/किसी विशेष JVM सेटअप/serialization के दौरान कुछ करने के साथ टूट सकता है? क्या ऐसे उदाहरण हैं जहां लोड Class deserialized एक जैसा नहीं होगा? दूसरे शब्दों में, क्या मैं Class ऑब्जेक्ट्स को क्रमबद्ध और deserialize करने के लिए अपने आवेदन में इस व्यवहार पर भरोसा कर सकता हूं?

+3

IMHO के लिए: एक deserialized वर्ग वस्तु पृथक होना चाहिए एक ही प्रकार के "मानक" वर्ग वस्तु का। Https://docs.oracle.com/javase/7/docs/api/serialized-form.html#java.lang.Class – Xvolks

उत्तर

2

जावा इस मामले में वस्तुओं को deserialize करने में सक्षम कैसे है ताकि पहचान संरक्षित है?

ऐसा इसलिए है क्योंकि कक्षा के उदाहरण क्लासलोडर द्वारा कैश किए जाते हैं।

Does Java guarantee that Object.getClass() == Object.getClass()?

इस व्यवहार एक विशेष वर्ग/लोड हो रहा है एक विशेष classloader का उपयोग कर/एक विशेष JVM सेटअप का उपयोग/क्रमबद्धता के दौरान कुछ कर रही के साथ टूट जा सकता है?

संकुल से कक्षाओं के धारावाहिक उदाहरणों के लिए java.* इस तोड़ा जा सकता है के साथ नहीं शुरू करने ObjectInputStream (एक उदाहरण here) में विभिन्न classloaders का उपयोग कर।

java.* अपने मामले की तरह में कक्षाओं के लिए (java.lang.Class), केवल बूटस्ट्रैप वर्ग लोडर उन्हें लोड कर सकते हैं, और कहा कि वर्ग परिभाषा दी वर्ग लोडर प्रति अद्वितीय है (JVM spec द्वारा गारंटी)

दूसरे शब्दों में, मैं अपने आवेदन में इस व्यवहार पर भरोसा कर सकते क्रमानुसार और deserialize कक्षा वस्तुओं

हाँ

+0

निश्चित रूप से 'क्लास' को क्लासलोडर द्वारा कैश किया गया है, मेरे लिए आश्चर्य की बात यह है कि _another_ JVM उदाहरण में बनाए गए 'क्लास' को deserializing वर्तमान JVM उदाहरण में 'कक्षा' उदाहरणों के साथ पहचान को संरक्षित करता है। इसलिए यदि मैं 'ऑब्जेक्टइनपूटस्ट्रीम' के मानक deserialization तर्क का उपयोग करता हूं, केवल एक एकल क्लासलोडर का उपयोग करें और समान कैनोलिक नाम वाले वर्गों के लिए अलग-अलग परिभाषाएं न हों, तो मैं सुनिश्चित कर सकता हूं कि 'कक्षा' वस्तुओं की पहचान deserialization के बाद संरक्षित की जाएगी? – gvlasov

+0

ध्यान दें कि यह आपको "कक्षा" के रूप में संदर्भित करता है वास्तव में कक्षा 'कक्षा' का एक उदाहरण है (जीभ-बहन के लिए खेद है)। इसलिए आपके पास प्रति वर्ग FQN का प्रतिनिधित्व करने वाले प्रति क्लासलोडर के कई उदाहरण नहीं हो सकते हैं। इसलिए उत्तर हाँ है, आप सुनिश्चित कर सकते हैं कि – idelvall

+0

यह भी ध्यान दें कि एक धारावाहिक ऑब्जेक्ट को deserializing ('कक्षा' सहित किसी भी वर्ग से) संस्करण भिन्न होने पर त्रुटियों का कारण बन सकता है ... – idelvall

0

जावा इस मामले में वस्तुओं को deserialize करने में सक्षम कैसे है ताकि पहचान संरक्षित है? ClasswriteObject()/readObject()/readResolve() लागू करने के लिए प्रतीत नहीं होता है।

यह readObject() या writeObject() यह पूरा करने के लागू करने के लिए की जरूरत नहीं है, लेकिन यह ObjectInputStream में readResolve(), को लागू करने से या विशेष तर्क के आधार पर यह कर सकता है।

+0

देखें, लेकिन यह एक टिप्पणी होनी चाहिए, जवाब नहीं। मैंने अपनी पोस्ट का उल्लेख करते हुए उल्लेख किया कि 'कक्षा' में 'readResolve() 'या तो नहीं है। – gvlasov

+0

यह एक टिप्पणी नहीं है। मैंने अब इस सवाल का जवाब दिया है जिसका जवाब इस उत्तर से दिया गया है।ऐसा लगता है कि यह एक गलत जवाब रहा है, मैंने इसे संशोधित किया है। – EJP

संबंधित मुद्दे