2012-09-20 20 views
14

मैंने पढ़ा है कि 7 से कम जावा संस्करण के साथ, जोडा टाइम ऑब्जेक्ट जावा के अंतर्निर्मित से अधिक विश्वसनीय हैं। एक उद्धृत कारण यह है कि जोदा वस्तुएं अपरिवर्तनीय हैं। यह फायदेमंद क्यों है? यदि मैं जोडा डेटटाइम ऑब्जेक्ट का साल, घंटा और टाइमज़ोन बदलना चाहता हूं, तो मुझे तीन प्रतियां बनाना होगा!जोडा वस्तुएं अपरिवर्तनीय क्यों हैं?

+1

इसके विपरीत, यदि आपकी डेटटाइम ऑब्जेक्ट्स अपरिवर्तनीय नहीं हैं, तो आप प्रत्येक तीसरे पक्ष एपीआई के पैरामीटर के रूप में इसे पास करते समय इसे क्लोन करने के लिए * माना जाता है ... क्योंकि जावा के पास 'const' नहीं है। –

उत्तर

18

यदि मैं जोडा डेटटाइम ऑब्जेक्ट का वर्ष, घंटा और टाइमज़ोन बदलना चाहता हूं, तो मुझे तीन प्रतियां बनाना होगा!

हां, वास्तव में। या आप पुराने ऑब्जेक्ट से सभी फ़ील्ड का उपयोग करके, एक नई ऑब्जेक्ट बना सकते हैं।

यह एक अच्छी तरह से अच्छी बात है - क्योंकि इसका मतलब है कि जब आप किसी वस्तु पर भरोसा नहीं करना चाहते हैं, तो यह नहीं होगा। ,

private static final Instant EARLIEST_ALLOWED_ARTICLE = ...; 

private Instant creationTimestamp; 

public Article(Instant creationTimestamp, ...) { 
    if (creationTimestamp.isBefore(EARLIEST_ALLOWED_ARTICLE)) { 
     throw new IllegalArgumetnException(...); 
    } 
    this.creationTimestamp = creationTimestamp; 
    ... 
} 

यह ठीक है, क्योंकि Instant अपरिवर्तनीय है: इस छद्म कोड पर विचार करें। यदि यह उत्परिवर्तनीय था, तो कन्स्ट्रक्टर में सत्यापन बेकार होगा - जब तक कि आप उस बिंदु पर रक्षात्मक प्रति नहीं बनाते।

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

असल में, यह आपको अपने कोड स्थानीय रूप से के बारे में कारण बताता है जो आप स्वीकार करते हैं और स्टोर करते हैं, या अन्य कोड पर वापस आते हैं। जब केवल आपका कोड आपकी ऑब्जेक्ट की स्थिति बदल सकता है, तो समय के साथ क्या होगा यह काम करना बहुत आसान है।

Joda समय वास्तव में कुछ हद तक विफल रहता है क्योंकि यह दोनों परिवर्तनशील और अपरिवर्तनीय प्रकार है - अगर आप सिर्फ इंटरफ़ेस (जैसे ReadableInstant) तो आप उन की गारंटी देता है नहीं मिलता है के लिए कार्यक्रम। यही कारण है कि Noda Time में मैंने सभी प्रकार के वास्तव में अपरिवर्तनीय बना दिया।

ब्याज से, क्या आप String उत्परिवर्तनीय होने के लिए चाहते हैं? यदि नहीं, तो इस बारे में सोचने की कोशिश करें कि क्या दो परिदृश्यों के बीच वास्तविक अंतर हैं।

+0

ये उत्कृष्ट अंक हैं। लेकिन तारीखें वास्तव में कुछ विशेष हैं, जैसे कि "प्राइमेटिव्स" (संख्याएं और तार) जो अपरिवर्तनीय हैं? आप जो वर्णन करते हैं वह सवाल उठाता है कि हमें * सभी * वर्गों को म्यूटेबल क्यों नहीं बनाना चाहिए और क्यों नहीं * हर * सेटटर * कभी भी मूल्य बदलने से पहले प्रतिलिपि बना रहा है। आपके द्वारा लिखे गए प्रत्येक सेटटर में 'क्लोन' या' कॉपी 'लिखना वास्तव में समझ में नहीं आता है। यह बदले में एक मौलिक समस्या पर संकेत देता है। – caw

+1

@caw: हाँ, मैं कहूंगा कि वास्तव में तिथियां * कुछ विशेष हैं। यह निश्चित रूप से उत्परिवर्तनीय प्रकारों के लिए सुविधाजनक हो सकता है, हालांकि मैं * आम तौर पर * जहां संभव हो वहां अपरिवर्तनीय पसंद करते हैं। लेकिन यदि निम्न स्तर के "आदिम" प्रकार सभी उत्परिवर्तनीय थे, तो * परिवर्तनशीलता या अपरिवर्तनीयता का * विकल्प * लागू करना बहुत कठिन होगा ... अपरिवर्तनीय कक्षाओं को हर समय * हर समय क्लोन करना होगा *। Urgh। –

+0

धन्यवाद! मुझे वास्तव में तारीखों और अन्य सामान्य वस्तुओं (जैसे संग्रह, 'कैलेंडर', व्यापार तर्क से वस्तुओं) के बीच मुख्य अंतर दिखाई नहीं देता है। वैसे भी, उन वस्तुओं के बीच एक * पर्याप्त * अंतर है जो बाद में नहीं बदला जा सकता है (और इस प्रकार कोई सार्वजनिक सेटर्स नहीं हो सकता है), जहां आपको अपने कन्स्ट्रक्टर/सेटर्स में प्राप्त डेटा को क्लोन करने की आवश्यकता है (जैसा कि उपर्युक्त आपके 'अनुच्छेद' उदाहरण में है, जो भी जोशुआ ब्लोच "प्रभावी जावा" में अनुशंसा करता है), और वस्तुओं को * बदलने के लिए * हैं, जिन्हें फिर प्रत्येक सेटटर में स्वयं को कॉपी करने की आवश्यकता होती है। – caw

3

सबसे आसान जवाब यह है कि एक बार जब आप ऑब्जेक्ट बनाते हैं, तो आप जानते हैं कि परिवर्तन नहीं कर सकता है। इसका अर्थ यह है कि आप ऐसी स्थिति में नहीं चले जाएंगे जहां आपका डेटा अप्रत्याशित तरीकों से बदलता है (कोड के अन्य हिस्सों या अलग-अलग धागे में)।

इससे ऑब्जेक्ट का व्यवहार अधिक अनुमानित और विश्वसनीय हो जाता है।

1

कई कारण हो सकते हैं लेकिन एक अच्छा हैशिंग का सम्मान करता है। अपरिवर्तनीय वस्तुओं का उपयोग हैशिंग डेटा संरचनाओं (जैसे हैशसेट, हैशमैप्स में चाबियाँ, आदि) में किया जा सकता है क्योंकि उनके हैश कोड और "समानता" अर्थशास्त्र नहीं बदलेगा। उत्परिवर्ती वस्तुएं हैशिंग के लिए उपयुक्त नहीं हैं क्योंकि उत्परिवर्तन उनके हैश कोड या समानता को बदल सकता है।

जोडा को अपरिवर्तनीय बनाने के द्वारा अब उन्हें हैशिंग डेटा संरचनाओं में उपयोग किया जा सकता है।

1

मुझे लगता है कि यह इस की वजह से है:

कल्पना कीजिए कि आप एक java.util.Date-वस्तु है, जो एक से अधिक कक्षाओं में प्रयोग किया जाता है। मैं एक वर्ग पर विकास कर रहा हूं, आप दूसरे पर। फिर, मैं तय करता हूं कि मुझे भविष्य की भविष्यवाणी करने की आवश्यकता है, लेकिन एक नई तिथि-वस्तु बनाने की बजाय, मैं वह हूं जो मेरे पास पहले से है, जिसे आप सोचते हैं कि समय में एक निश्चित बिंदु का प्रतिनिधित्व करता है, और मैं इसमें तीन घंटे जोड़ता हूं। अब, आपका कोड रनटाइम पर गंभीर समस्याओं में भाग सकता है। यह सब एक अपरिवर्तनीय वस्तु का उपयोग करके टाला जा सकता है, क्योंकि आप इसकी स्थिति नहीं बदल सकते हैं, आप इसे किसी और के लिए गड़बड़ नहीं कर सकते हैं।

1

दुर्भाग्य से, डेटटाइम का कार्यान्वयन अपरिवर्तनीय नहीं है [1], क्योंकि final का उपयोग नहीं किया जाता है।

https://github.com/JodaOrg/joda-time/blob/master/src/main/java/org/joda/time/DateTime.java

[1] शब्द "अपरिवर्तनीय" सामान्य तौर पर "धागा सुरक्षित अपरिवर्तनीय" मतलब समझा जाता है।

+0

मुझे समझ में नहीं आता .. डेटटाइम एक 'अंतिम' वर्ग है, और यदि आपका मतलब 'बेसडेट टाइम' में फ़ील्ड है तो हाँ वे 'अंतिम' नहीं हैं और प्रतिबिंब का उपयोग करके संशोधित किया जा सकता है लेकिन इस तरह 'स्ट्रिंग' भी नहीं है अपरिवर्तनीय। – Premraj

+0

फ़ाइनल किसी को प्रतिबिंब के साथ संशोधित करने से नहीं रोकता है .. – Tobb

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