2015-04-13 5 views
6

मैं सीखने की कोशिश कर रहा हूं कि धारावाहिक जावा और उसके सबसे पुराने संस्करण के साथ कैसे काम करता है। मैं इस तरह एक लैम्ब्डा क्रमानुसार करने कोशिश कर रहा हूँ:धारावाहिक लैम्ब्डा और कोई serialVersionUID?

Runnable r = (Runnable & Serializable)() -> {System.out.println("This is a test");}; 

लेकिन मैं नोटिस कि मैं एक serialVersionUID चर के अभाव के बारे में कोई चेतावनी है। क्या यह सामान्य है ?

मैं जानता हूँ कि यह क्रम तथापि पर उत्पन्न हो जाएगा यह दृढ़ता से इसे परिभाषित करने की सिफारिश की है: https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html

एक serializable वर्ग स्पष्ट रूप से एक serialVersionUID की घोषणा नहीं करता है, तो क्रमबद्धता क्रम की गणना करेगा एक डिफ़ॉल्ट serialVersionUID जावा (टीएम) ऑब्जेक्ट सीरियलाइजेशन विशिष्टता में वर्णित अनुसार, कक्षा के विभिन्न पहलुओं के आधार पर उस वर्ग के लिए मूल्य। हालांकि, यह सलाह दी जाती है कि सभी serializable वर्गों स्पष्ट serialVersionUID मूल्यों की घोषणा के बाद से डिफ़ॉल्ट serialVersionUID गणना अत्यधिक करने के लिए वर्ग विवरण संकलक कार्यान्वयन के आधार पर भिन्न हो सकता है कि संवेदनशील है, और इस प्रकार अक्रमांकन दौरान अप्रत्याशित InvalidClassExceptions हो सकती है। इसलिए, एक अलग serialVersionUID विभिन्न जावा कंपाइलर कार्यान्वयन में मूल्य की गारंटी के लिए, एक serializable कक्षा को एक स्पष्ट serialVersionUID मान घोषित करना होगा। यह भी दृढ़ता से सलाह देता है कि स्पष्ट serialVersionUID घोषणाएं निजी संशोधक का उपयोग करें जहां संभव हो, क्योंकि ऐसी घोषणाएं केवल पर लागू होती हैं, तुरंत घोषित कक्षा - सीरियल VersionUID फ़ील्ड विरासत वाले सदस्यों के रूप में उपयोगी नहीं हैं। ऐरे कक्षाएं एक स्पष्ट serialVersionUID घोषित नहीं कर सकती हैं, इसलिए उनके पास हमेशा डिफ़ॉल्ट गणना मूल्य होता है, लेकिन सेरियल VersionUID मानों के मिलान की आवश्यकता सरणी कक्षाओं के लिए छूट दी जाती है।

मुझे क्या करना चाहिए? मैं इसे अपने लैम्ब्डा में कैसे परिभाषित कर सकता हूं?

धन्यवाद

+1

परिभाषित वर्ग की कमी के कारण फ़ील्ड 'serialVersionUID 'घोषित करने का कोई तरीका नहीं है। और यह सीधे अगले प्रश्न की ओर जाता है: किस कारण से लैम्ब्डा क्रमबद्ध होना चाहिए? इसमें फ़ील्ड नहीं हैं और इस प्रकार कोई डेटा नहीं है! – Seelenvirtuose

+1

@ सेलेनविर्टुओस एक धारावाहिक लैम्ब्डा में वे मान होते हैं जिन्हें लैम्ब्डा का मूल्यांकन किया गया था। यदि विभिन्न कब्जे वाले मूल्यों के साथ एक लैम्ब्डा का मूल्यांकन कई बार किया जाता है, तो लैम्बडास को जोड़ने वाली वस्तुएं अलग-अलग होंगी, और उनके क्रमबद्ध प्रतिनिधित्व भी होंगे। –

+0

@StuartMarks जाहिर है, मैंने काफी दूर नहीं सोचा था। इस पर ध्यान दिलाने के लिए धन्यवाद। असल में, इससे मुझे अपने दिमाग को बदलने (निर्माण?) में मदद मिली। – Seelenvirtuose

उत्तर

6

serialVersionUID केवल वर्ग है जो एक stream identifier उत्पन्न करने के लिए प्रासंगिक है। यह मामला नहीं है यदि serializable वर्ग में writeReplace() विधि (Serializable documentation में भी वर्णित है) जो एक अलग वर्ग का एक विकल्प वस्तु देता है, क्योंकि इस तरह का प्रतिनिधित्व मूल वर्ग से पूरी तरह से समाप्त हो जाता है। यह वही है serializable लैम्ब्डा उदाहरणों के साथ होता है, SerializedLambda देखें:

ऐसे compilers या भाषा क्रम पुस्तकालयों के रूप में serializable lambdas का कार्यान्वयन करने, सुनिश्चित करें कि उदाहरणों ठीक से deserialize की संभावना है। ऐसा करने का मतलब यह है कि writeReplace विधि डिफ़ॉल्ट क्रमबद्धता को आगे बढ़ने की अनुमति देने के बजाय SerializedLambda का एक उदाहरण देता है।

तो यह SerializedLambda का एक उदाहरण है कि धारा पर समाप्त होता है और इस तरह उस वर्ग की जिम्मेदारी एक स्थिर धारावाहिक प्रतिनिधित्व करने के लिए है। दुर्भाग्यवश यह संभव असंगतताओं से आपकी रक्षा नहीं करता है।

अक्रमांकन पर, वर्ग लैम्ब्डा अभिव्यक्ति को परिभाषित करने की एक कृत्रिम विधि कहा जाता हो जाएगा जो अक्रमांकन प्रयास जो कि वर्ग के भीतर एक लैम्ब्डा अभिव्यक्ति के एक मौजूदा परिभाषा से मेल नहीं खाते को अस्वीकार कर देंगे (this और this answer की तुलना), मिलान, जबकि लैम्ब्डा की परिभाषा के सूक्ष्म पहलुओं पर निर्भर हो सकता है। ध्यान दें कि javac के बजाय एक्लिप्स के साथ परिभाषित वर्ग को फिर से संकलित करना सीरियलाइजेशन संगतता को तोड़ सकता है।

security impacts of Serializable lambdas भी नहीं। आम तौर पर, मैं इसका उपयोग करने से बचने की सलाह देता हूं।

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