2011-08-22 9 views
17

निम्नलिखित कोड:एक धारावाहिक आंतरिक वर्ग धारावाहिक क्यों नहीं है?

public class TestInnerClass { 

    public static void main(String[] args) throws IOException { 
     new TestInnerClass().serializeInnerClass(); 
    } 

    private void serializeInnerClass() throws IOException { 
     File file = new File("test"); 
     InnerClass inner = new InnerClass(); 
     new ObjectOutputStream(new FileOutputStream(file)).writeObject(inner); 
    } 

    private class InnerClass implements Serializable { 

     private static final long serialVersionUID = 1L; 

    } 

} 

निम्नलिखित अपवाद फेंकता है:

Exception in thread "main" java.io.NotSerializableException: TestInnerClass 

मुझे लगता है कि भीतरी वर्ग एक TestInnerClass.this क्षेत्र है कि TestInnerClass के खेतों और तरीकों को यह निजी उपयोग की अनुमति देता है। आंतरिक वर्ग स्थिर solves it घोषित करना, लेकिन यदि InnerClass को इस पहुंच की आवश्यकता है तो क्या होगा? संलग्न वर्ग के बिना एक गैर स्थैतिक आंतरिक कक्षा को क्रमबद्ध करने का कोई तरीका है, उदा। बाहरी वर्ग transient का संदर्भ बनाकर?

संपादित करें: उदाहरण के लिए, बाहरी वर्ग तक पहुंच केवल क्रमिकरण से पहले ही आवश्यक हो सकती है। ठीक है, संकलक इसे नहीं जानता, लेकिन मैंने सोचा कि यही कारण है कि transient कीवर्ड मौजूद है।

+4

आप भीतरी वर्ग स्थिर घोषित करने के लिए कोशिश की थी? 'निजी स्थैतिक वर्ग इनरक्लास ' – gnat

उत्तर

20

क्या हुआ अगर InnerClass इस उपयोग की जरूरत है?

फिर इसे बाहरी वर्ग के उदाहरण की आवश्यकता है, और इसे आंतरिक कक्षा के साथ क्रमबद्ध किया जाना चाहिए।

क्या संलग्न वर्ग के बिना एक गैर स्थैतिक आंतरिक कक्षा को क्रमबद्ध करने का कोई तरीका है, उदा। बाहरी वर्ग क्षणिक के संदर्भ में?

नहीं। जब आप इस तरह के वर्ग को deserialize करते हैं और फिर बाहरी वर्ग की एक उदाहरण विधि को कॉल करने का प्रयास करेंगे तो क्या होगा? एक NullPointerException? क्योंकि यह दृष्टांत को

+1

मेरी स्थिति में, आंतरिक वर्ग को वास्तव में धारावाहिक होने से पहले पहुंच की आवश्यकता होती है (deserialization के बाद नहीं)। इसके बाद इसे केवल सुपरक्लास के रूप में उपयोग किया जाता है जो बाहरी वर्ग के बारे में नहीं जानता है। – tb189

+5

@ tb189: आप हमेशा 'इनर क्लास' में फ़ील्ड 'क्षणिक TestInnerClass parentClass' जोड़कर गैर स्थैतिक निर्भरता को तोड़ सकते हैं और deserializing जब इसका ख्याल रखना। –

+0

यह वास्तव में इसके साथ निपटने का एक तरीका होगा, और 'TestInnerClass.this' के क्षणिक संदर्भ जैसा दिखता है। – tb189

1

TestInnerClass serializable बनाने के बारे में कैसे?

public class TestInnerClass implements Serializable { } 
+2

यह संभव है, लेकिन हमेशा वांछित नहीं है, क्योंकि यह धारावाहिक वर्ग में बहुत अधिक डेटा जोड़ता है। – tb189

+0

@EJP: हमेशा ऐसे समाधान होते हैं जो अधिक बेहतर हो सकते हैं (आंतरिक कक्षा के उन हिस्सों को अलग करना जिन्हें एक्सेस की आवश्यकता होती है और फिर इसे एक स्थिर क्रमिक वर्ग में अग्रेषित करें, एक क्षणिक फ़ील्ड TestInnerClass का उपयोग करके, आंतरिक कक्षा में एक और धारावाहिक वस्तु को बनाए रखने)। यह बाहरी वर्ग क्षणिक में सभी क्षेत्रों को घोषित करने का भी अर्थ देगा, जो एक डिजाइन दोष की तरह लगता है। ऐसा इसलिए नहीं है क्योंकि वर्तमान स्थिति काम नहीं करती है कि पहले वैकल्पिक/हैक का तुरंत उपयोग किया जाना चाहिए। – tb189

0

InnerClass धारावाहिक नहीं किया जा सकता है (जैसा कि अक्रमांकन के दौरान आवश्यक) आप बाहरी वर्ग का एक उदाहरण के बिना बाहरी वर्ग

इनर क्लासों उदाहरण मौजूद नहीं कर सकते का एक उदाहरण के लिए एक संदर्भ की जरूरत है।

यानी

OuterClass o = new OuterClass(); 
OuterClass.InnerClass o_i = o.new InnerClass(); 

आप स्थिर भीतरी वर्ग का उपयोग करते हैं, इसलिए यह स्थिर भीतरी वर्ग serialise करना संभव हो जाएगा। स्थैतिक आंतरिक वर्गों के उदाहरण स्टैंडअलोन बनाया जा सकता है।

यानी

OuterClass o = new OuterClass(); 
OuterClass.InnerClass i = new OuterClass.InnerClass(); 
+0

शायद एक गिथब गिस्ट या एक पूर्ण पुनरुत्पादित उदाहरण बनाना अच्छा होगा, आपको नहीं लगता? – Adonis