2008-09-03 22 views
7

जावा में, स्थैतिक और क्षणिक फ़ील्ड क्रमबद्ध नहीं हैं। हालांकि, मुझे पता चला कि स्थैतिक क्षेत्रों की शुरुआत से जेनरेट किए गए serialVersionUID को बदला जा सकता है। उदाहरण के लिए, static int MYINT = 3; serialVersionUID को बदलने का कारण बनता है। इस उदाहरण में, यह समझ में आता है क्योंकि कक्षा के विभिन्न संस्करणों को विभिन्न प्रारंभिक मान मिलेंगे। कोई प्रारंभिकरण serialVersionUID क्यों बदलता है? उदाहरण के लिए, static String MYSTRING = System.getProperty("foo"); भी serialVersionUID को बदलने का कारण बनता है।स्थिर प्रारंभिकरण के साथ जावा क्रमबद्धता

विशिष्ट होने के लिए, मेरा प्रश्न यह है कि एक विधि के साथ प्रारंभिकरण serialVersionUID को बदलने का कारण बनता है। मेरी समस्या यह है कि मैंने एक नया स्थैतिक क्षेत्र जोड़ा जो सिस्टम प्रॉपर्टी वैल्यू (getProperty) के साथ शुरू किया गया था। उस परिवर्तन ने रिमोट कॉल पर एक क्रमबद्ध अपवाद का कारण बना दिया।

उत्तर

5

आप bug 4365406 और algorithm for computing serialVersionUID में इसके बारे में कुछ जानकारी पा सकते हैं। असल में, सदस्य System.getProperty() के साथ प्रारंभ करने के दौरान, संकलक System कक्षा (मुझे लगता है कि System कक्षा को पहले आपकी कक्षा में संदर्भित नहीं किया गया था) के संदर्भ में आपकी कक्षा में एक नई static संपत्ति प्रस्तुत करती है, और चूंकि यह गुण कंपाइलर द्वारा पेश किया गया है निजी नहीं है, यह serialVersionUID गणना में भाग लेता है।

नैतिकता: हमेशा स्पष्ट serialVersionUID उपयोग करते हैं, आप कुछ CPU चक्र और कुछ सिर दर्द :)

0

यदि मैं सही ढंग से spec को पढ़ता हूं तो स्वचालित serialVersionUID बदलना नहीं चाहिए यदि आप क्षणिक क्षेत्र की स्थिरता का मान बदलते हैं। स्पेक के Chapter 5.6 पर एक नज़र डालें।

हालांकि, अगर आप इस बारे में थोड़ा लगता है - आप एक वस्तु है कि static int MYINT = 3, जब आप तो वर्ग आप एक ही वस्तु वापस प्राप्त करने की उम्मीद deserialize serializing से शुरू करते हैं, कि MYINT = 3 साथ, है। इसलिए, यदि आप स्थिर प्रारंभिक परिवर्तन को बदलते हैं तो आप serialVersionUID को बदलने के लिए अपेक्षा करेंगे क्योंकि आप एक ही ऑब्जेक्ट को फिर से प्राप्त नहीं कर सकते हैं।

फिर भी, अपने सभी serializable वर्गों में रखना और आप serialVersionUID नियंत्रित कर सकते हैं:

private static final long serialVersionUID = 7526472295622776147L; 
0

मैं सवाल अद्यतन और अधिक स्पष्ट किया जाना है। मैं समझता हूं कि एक शाब्दिक परिवर्तन के साथ प्रारंभिक परिवर्तन serialVersionUID क्यों नहीं है, लेकिन क्यों गतिशील प्रारंभिकता इसे बदलती है। यदि आप किसी विधि के साथ आरंभ करते हैं, तो निश्चित रूप से मूल्य हमेशा अलग हो सकता है।

serialVersionUID सेट करना केवल कक्षा के बाद के संस्करण में ठीक है, यदि आप सुनिश्चित हैं कि यह एक सुरक्षित परिवर्तन है।

2

स्वचालित serialVersionUID एक वर्ग के सदस्यों के आधार पर गणना की जाती है बचा सकते हैं। इन्हें सूर्य जेडीके में जावप टूल का उपयोग करके कक्षा फ़ाइल के लिए दिखाया जा सकता है।

प्रश्न में उल्लिखित मामले में, जो सदस्य जोड़ा/हटाया गया है वह स्थिर प्रारंभिक है। यह वर्ग फ़ाइलों में() वी के रूप में प्रकट होता है। विधि की सामग्री javap -c का उपयोग करके अलग किया जा सकता है। आप System.getProperty ("foo") कॉल और MYSTRING को असाइनमेंट करने में सक्षम होना चाहिए। हालांकि एक स्ट्रिंग शाब्दिक (या जावा भाषा विशिष्टता द्वारा परिभाषित किसी भी संकलन-समय निरंतर) के साथ एक असाइनमेंट सीधे क्लास फ़ाइल द्वारा समर्थित है, इसलिए एक स्थिर प्रारंभकर्ता की आवश्यकता को हटा रहा है।

कोड लक्ष्यीकरण जे 2 एसई 1.4 (उपयोग-स्रोत 1.4-लक्ष्य 1.4) या पहले के लिए एक सामान्य मामला पुरानी कक्षा के उदाहरणों के लिए स्थैतिक फ़ील्ड है जो स्रोत कोड (MyClass.class) में कक्षा अक्षर के रूप में दिखाई देता है। क्लास इंस्टेंस क्लास.forनाम के साथ मांग पर देखा जाता है, और एक स्थिर क्षेत्र में संग्रहीत किया जाता है। यह स्थिर क्षेत्र है जो serialVersionUID को बाधित करता है। जे 2 एसई 5.0 से, एलडीसी ओपोड का एक संस्करण कक्षा साहित्य के लिए प्रत्यक्ष समर्थन देता है, सिंथेटिक क्षेत्र की आवश्यकता को हटा देता है। फिर, यह सब javap -c के साथ दिखाया जा सकता है।

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