2016-08-01 8 views
8

जावा भाषा को इसमें enums जोड़ने से बहुत फायदा हुआ; लेकिन दुर्भाग्य से वे अलग-अलग कोड स्तर वाले सिस्टम के बीच धारावाहिक वस्तुओं को भेजते समय अच्छी तरह से काम नहीं करते हैं।क्या जावा में सीरियलाइजिंग एनम्स के लिए अच्छे विकल्प हैं?

उदाहरण: मान लें कि आपके पास दो सिस्टम ए और बी हैं। वे दोनों एक ही कोड स्तर के साथ शुरू होते हैं, लेकिन किसी बिंदु पर समय पर विभिन्न बिंदुओं पर कोड अपडेट देखना शुरू होता है। अब मान लें कि कुछ

public enum Whatever { FIRST; } 

और ऐसी अन्य वस्तुएं हैं जो उस enum के स्थिरांक के संदर्भ रखती हैं। उन वस्तुओं को क्रमबद्ध किया जाता है और ए से बी या इसके विपरीत भेजा जाता है। अब विचार करना बी जो भी के एक नए संस्करण

public enum Whatever { FIRST; SECOND } 

तब है:

class SomethingElse implements Serializable { ... 
    private final Whatever theWhatever; 
    SomethingElse(Whatever theWhatever) { 
    this.theWhatever = theWhatever; .. 

instantiated हो जाता है ...

SomethingElse somethin = new SomethingElse(Whatever.SECOND) 

और फिर धारावाहिक और अधिक के रूप में उदाहरण के लिए (ए के लिए भेजा कुछ आरएमआई कॉल का नतीजा)। जो बुरा है, क्योंकि अब ए पर deserialization के दौरान एक त्रुटि होगी: ए जानता है कि जो भी enum वर्ग है, लेकिन एक संस्करण में जो SECOND नहीं है।

हमने इसे कठिन तरीका बताया; और अब मैं उन परिस्थितियों के लिए enums का उपयोग करने के लिए बहुत उत्सुक हूं जो वास्तव में "enums के लिए एकदम सही" होगा; सिर्फ इसलिए कि मुझे पता है कि मैं आसानी से मौजूदा एनम को विस्तारित नहीं कर सकता।

अब मैं सोच रहा हूं: क्या इस तरह की संगतता समस्याओं से बचने के लिए वहां (अच्छी) रणनीतियां हैं? या मुझे वास्तव में "प्री-एनम" समय पर वापस जाना है; और enums का उपयोग नहीं करते हैं, लेकिन एक समाधान पर भरोसा करना है जहां मैं जगह पर सादा तार का उपयोग करें?

अद्यतन: कृपया ध्यान दें कि serialversionuid का उपयोग करके यहां सहायता नहीं करता है। यह बात केवल आपको एक असंगत परिवर्तन "अधिक स्पष्ट" बनाने में मदद करती है। लेकिन मुद्दा यह है: मुझे परवाह नहीं है कि क्यों deserialization विफल रहता है - क्योंकि मुझे ऐसा होने से बचना है। और मैं अपनी वस्तुओं को क्रमबद्ध करने के तरीके को बदलने की स्थिति में भी नहीं हूं। हम आरएमआई कर रहे हैं; और हम बाइनरी के लिए क्रमबद्ध कर रहे हैं; मेरे पास इसे बदलने का कोई मतलब नहीं है।

+6

क्या यह किसी भी वर्ग के साथ कोई मुद्दा नहीं होगा? यदि आप फ़ील्ड को किसी नए संस्करण में बदलते हैं, तो पुराने संस्करण के लिए deserialization विफल हो जाएगा। – 4castle

+0

जरूरी नहीं है। फ़ील्ड जोड़ना एक पूरी तरह से वैध ऑपरेशन है। और यदि आप सादे तारों के साथ काम करते हैं तो आप स्पष्ट रूप से संकलन समय की जांच ढीला करते हैं; लेकिन यदि कोई ऑब्जेक्ट फ़ील्ड स्ट्रिंग है, तो वह फ़ील्ड बिना किसी समस्या के ** ** ** किसी भी मूल्य को ले जा सकता है। – GhostCat

+1

आप स्थिरांक का उपयोग कर सकते हैं- ये अच्छी तरह से क्रमबद्ध हैं, और उनके पास कई enum-like गुण हैं –

उत्तर

0

वापस विभिन्न समाधान के बारे में जा रहा है और आगे के बाद, मैं एक समाधान @GuiSim से सुझाव के आधार पर लगा: एक एक वर्ग है कि एक enum मान का निर्माण कर सकते ।यह वर्ग

  1. कस्टम deserialization कर सकते हैं; इस प्रकार मैं रोका जा सकता है वहाँ deserialization प्रक्रिया
  2. अगर है() और getEnumValue (जैसे सरल तरीकों प्रदान के दौरान अपवाद) नहीं होगा: पहले एक आपको बताता है कि enum अक्रमांकन वास्तव में काम किया, और दूसरा एक deserialized enum (या एक अपवाद फेंकता है)
6

जैसा कि @ जेस्पर टिप्पणियों में उल्लिखित है, मैं आपके इंटर-सेवा संचार के लिए जेएसओएन की तरह कुछ सुझाऊंगा। इससे आपको अधिक नियंत्रण हो सकता है कि एनम मूल्यों को कितना अज्ञात किया जाता है।

उदाहरण के लिए, हमेशा भयानक Jackson का उपयोग करके आप Deserialization FeaturesREAD_UNKNOWN_ENUM_VALUES_AS_NULL या READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE का उपयोग कर सकते हैं। जब आप फिट दिखाई देते हैं तो दोनों आपके एप्लिकेशन तर्क को अज्ञात enum मानों को संभालने की अनुमति देंगे।

उदाहरण (जैक्सन दस्तावेज़ से सीधे)

enum MyEnum { A, B, @JsonEnumDefaultValue UNKNOWN } 
... 
final ObjectMapper mapper = new ObjectMapper(); 
mapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE); 

MyEnum value = mapper.readValue("\"foo\"", MyEnum.class); 
assertSame(MyEnum.UNKNOWN, value); 
+0

निश्चित चीज़; लेकिन कम से कम अब के लिए, हमारे वास्तुकला के रूप में है; इस तरह के मौलिक परिवर्तन के लिए कोई मौका नहीं है। हमें वर्षों के लिए धारावाहिक वस्तुओं के साथ रहना है ... – GhostCat

+0

@GostCat मुझे लगता है कि आप [कस्टम जावा deserialization] (http://stackoverflow.com/questions/7290777/java-custom-serialization) का उपयोग कर सकते हैं यह परिभाषित करने के लिए कि कैसे enums deserialized हैं और अज्ञात मूल्यों को कैसे प्रबंधित किया जाता है। – GuiSim

+2

अनुपूरक: मुझे लगता है कि कस्टम क्रमबद्धता ** ** ** काम नहीं करेगा - enums अलग-अलग संभाले जाते हैं (देखें http://stackoverflow.com/questions/15521309/is-custom-enum-serializable-too) यह कहता है * जिस प्रक्रिया से enum स्थिरांक serialized हैं * अनुकूलित नहीं किया जा सकता है। – GhostCat

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