2013-03-21 2 views
5

यह आइटम प्रभावी जावा पुस्तक का कोई 74 एक पैराग्राफ जो नीचे के अनुसार उल्लेख है (आइटम 74 के अंतिम से 2 पैरा) है:प्रभावी जावा मद कोई 74 (क्रमबद्धता पर): लागू Serializable विवेकपूर्ण तरीके से

आंतरिक वर्ग (आइटम 22) Serializable लागू नहीं करना चाहिए। वे संकलक-जेनरेट सिंथेटिक फ़ील्ड का उपयोग उदाहरणों और को 0xस्कॉप्स को संलग्न करने से स्थानीय चर के मानों को संग्रहीत करने के संदर्भों को संग्रहीत करने के संदर्भों को संग्रहीत करने के लिए करते हैं। ये फ़ील्ड कक्षा परिभाषा के अनुरूप कैसे हैं निर्दिष्ट, अज्ञात और स्थानीय वर्गों के नाम हैं। इसलिए, आंतरिक कक्षा का डिफ़ॉल्ट क्रमबद्ध रूप बीमार है- परिभाषित किया गया है।

मुझे आंतरिक वर्ग के बारे में पता है जो कंपाइलर जेनरेट सिंथेटिक फ़ील्ड का उपयोग संलग्न उदाहरणों के संदर्भ में संग्रहीत करने के लिए करता है उदा। यदि संलग्न वर्ग MyEnclosing और आंतरिक वर्ग MyInner है तो संलग्न संदर्भ MyEnclosing.this है। लेकिन मैं बोल्ड भाग प्राप्त करने में सक्षम नहीं हूं। कृपया मुझे अर्थ प्राप्त करने में मदद करें। धन्यवाद!!!

उत्तर

6

मान लीजिए आपके पास इस तरह एक स्थानीय वर्ग:

class OuterClass { 
    Runnable run; 

    void method() { 
     final int a = 8; 
     this.run = new Runnable() { 
      public void run() { 
      System.out.println(a); 
      } 
     }; 
    } 
} 

अब मैं this है, जो इस भीतरी वर्ग प्रकार का ऑब्जेक्ट शामिल क्रमानुसार करने की कोशिश लगता है। मेरे कंपाइलर नाम वर्ग OuterClass$1 और इसे val$a नामक फ़ील्ड देता है। लेकिन इस स्थिति में उपयोग किए जाने वाले सटीक नाम कंपाइलर के spec का हिस्सा नहीं हैं। एक और कंपाइलर आंतरिक कक्षा OuterClass$method$1 पर कॉल करना चुन सकता है। उस स्थिति में, एक संकलित संस्करण में क्रमबद्ध करना और दूसरे में deserializing विफल हो जाएगा, भले ही एक ही स्रोत फ़ाइल का उपयोग किया गया था।

(। इसके अलावा, वहाँ भी है समस्या यह है कि एक गुमनाम आंतरिक वर्ग नो args निर्माता नहीं है लेकिन इसके बाद के संस्करण की समस्या के कारण, यहां तक ​​कि एक नामित भीतरी वर्ग मज़बूती से क्रमानुसार नहीं कर सकता)

+0

आपके प्रयास के लिए धन्यवाद। आप मूल रूप से कहना चाहते हैं कि वैल $ ए कंपाइलर द्वारा आंतरिक कक्षा में संग्रहीत चर है जो (वैल $ ए) आउट क्लास का हिस्सा है। क्या मैं सही हूँ? यदि मैं सही हूं तो समस्या क्या है आंतरिक कक्षा को क्रमबद्ध नहीं करना। असल में मैं आपका प्राप्त नहीं कर पा रहा हूं "लेकिन इस स्थिति में उपयोग किए जाने वाले सटीक नाम कंपाइलर के spec" भाग का हिस्सा नहीं हैं। – Trying

+1

मुझे पूरा यकीन है कि मैंने क्लास फाइलों को एक नामकरण सम्मेलन के साथ देखा है जो 'बाहरी क्लास $ 1' के बजाय' बाहरी क्लास $ विधि $ 1' को आंतरिक कक्षा कहलाता है (हालांकि मैंने अभी कई कंपाइलर्स की कोशिश की है और सक्षम नहीं था इसे पुन: उत्पन्न करने के लिए)। बिंदु [spec] (http://jcp.org/aboutJava/communityprocess/maintenance/JLS/innerclasses.pdf) केवल तभी आवश्यक है कि संकलक $, अक्षरों, और कुछ संयोजनों को जोड़कर एक अद्वितीय नाम बनाये। संलग्न वर्ग नाम के बाद संख्याएं। और यदि वर्ग का नाम बदल गया, तो deserialization विफल हो जाएगा। –

+0

मैं थोड़ी उलझन में हूं ... जब आप 'इस' को क्रमबद्ध कर रहे हों तो आपकी अनाम' रननेबल 'क्लास को धारावाहिक क्यों मिलेगा? केवल आपके बाहरी वर्ग के खेतों को क्रमबद्ध किया जाता है। और सवाल वास्तव में आंतरिक/स्थानीय/अज्ञात वर्ग को 'Serializable'' के रूप में संदर्भित करता है ... –

1

पर विचार करें निम्नलिखित कोड:

public class Main { 
    public static void main(String[] args) { 
     final int x = Integer.valueOf(args[0]); 
     new Object() { 
      void print() { 
       System.out.println(x); 
      } 
     }.print(); 
    } 
} 

मेरे संकलक गुमनाम आंतरिक वर्ग Main$1 कहता है। जब मैंने इसे एकत्रित न, मुझे लगता है कि बाहरी दायरे से x का मूल्य की एक प्रति के लिए एक निजी क्षेत्र val$x कहा जाता है में संग्रहित है:

private final int val$x; 

यह बोल्ड हिस्सा किस बारे में बात कर रही है का एक उदाहरण है।

0

एक आंतरिक वर्ग एक गैर स्थैतिक कक्षा कुछ अन्य वर्ग के भीतर परिभाषित किया गया है:

class Outer implements Serializable { 
    private String someString; 

    class Inner implements Serializable { 
     private int someInt; 
    } 

} 

एक बार जब आप Inner वर्ग का एक उदाहरण है, जब आप इसे क्रमानुसार, यह बाहरी वर्ग के लिए एक संदर्भ होना आवश्यक है (जो इसे Outer.this संदर्भ के माध्यम से आंतरिक रूप से एक्सेस करता है) और एक धारावाहिक वस्तु के लिए यह कैसे प्राप्त किया जाता है निर्दिष्ट नहीं है। एक ही एक स्थानीय वर्ग के लिए लागू होता है:

class Outer implements Serializable { 
    private String someString; 

    Serializable method(final int i) { 
     class Inner implements Serializable { 
      Inner() { 
       System.out.println(i); 
      } 
     } 
     return new Inner(); 
    } 
} 

आप method() द्वारा दिए गए मान को क्रमानुसार है, यह i के लिए एक संदर्भ की आवश्यकता है, लेकिन है कि विश्वसनीय नहीं है।

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