2008-11-06 24 views
14

एक सहयोगी ने हाल ही में मुझसे पूछा कि मैप को गहराई से कैसे क्लोन करें और मुझे एहसास हुआ कि मैंने कभी क्लोन() विधि का उपयोग नहीं किया है- जो मुझे चिंतित करता है।आपने ऑब्जेक्ट.क्लोन() के लिए क्या उपयोग किया है?

आपको किसी ऑब्जेक्ट को क्लोन करने की आवश्यकता वाले सबसे आम परिदृश्य क्या हैं?

उत्तर

15

मुझे लगता है कि आप जावा में Object.clone() का जिक्र कर रहे हैं। यदि हां, तो सलाह दीजिये कि Object.clone() में कुछ प्रमुख समस्याएं हैं, और अधिकांश मामलों में इसका उपयोग निराश हो जाता है। कृपया पूर्ण उत्तर के लिए जोशुआ ब्लोच द्वारा "Effective Java" से आइटम 11 देखें। मेरा मानना ​​है कि आप प्राइमेटिव टाइप एरे पर सुरक्षित रूप से Object.clone() का उपयोग कर सकते हैं, लेकिन इसके अलावा आपको क्लोन का सही उपयोग और ओवरराइड करने के बारे में उचित होने की आवश्यकता है। आप शायद एक कॉपी कन्स्ट्रक्टर या एक स्थैतिक फैक्ट्री विधि को परिभाषित करने से बेहतर हैं जो स्पष्ट रूप से ऑब्जेक्ट को आपके अर्थशास्त्र के अनुसार क्लोन करता है।

+2

सही - सबसे आम परिदृश्य "क्लोन का उपयोग न करें।" –

+0

लिंक टूट गया था। –

+0

साइट आर्टिमा से यह लिंक मिला: http://www.artima.com/intv/bloch13.html –

5

सबसे आम तौर पर, जब मुझे एक कॉलर को एक म्यूटेबल ऑब्जेक्ट वापस करना होता है, तो मुझे चिंता है कि कॉलर शायद थ्रेड-असभ्य तरीके से मिल जाए। सूची और तारीख वे हैं जो मैं इसे सबसे अधिक करता हूं। यदि कॉलर एक सूची में फिर से शुरू करना चाहता है और मुझे धागे संभवतः इसे अपडेट कर रहे हैं, तो क्लोन या इसकी प्रतिलिपि वापस करना सुरक्षित है।

असल में, यह कुछ लाता है जिसके लिए मुझे एक और प्रश्न खोलना होगा: कॉपी कन्स्ट्रक्टर या क्लोन? जब मैंने सी ++ किया, तो हमने हमेशा एक कॉपी कन्स्ट्रक्टर किया और इसके साथ क्लोन लागू किया, लेकिन अगर आप एक प्रतिलिपि बनाने वाले का उपयोग करके अपने क्लोन को कार्यान्वित करते हैं तो FindBugs इसे पसंद नहीं करते हैं।

+0

आप क्लोन() लागू करने के लिए, बल्कि super.clone लागू(), जब कोई उप-वर्गों अपने वर्ग और क्लोन का आह्वान वे सुपर क्लास प्रकार, नहीं उपवर्ग प्रकार का ऑब्जेक्ट मिल जाएगा की तुलना में एक प्रतिलिपि निर्माता का उपयोग करते हैं। –

+0

@ डैन, हां, यह बहुत कुछ है जो FindBugs ने कहा था। और कुछ ऐसा पढ़ा जो StackOverflow उत्तर से C++ के बारे में एक प्रश्न से जुड़ा हुआ था, अब मैं समझ सकता हूं कि सी ++ में ऐसा करने से यह बहुत अच्छा नहीं था। –

+0

सी ++ में कॉपी कन्स्ट्रक्टर के साथ क्लोन कार्यान्वित करना: हर्ब सटर कहेंगे "यहां ड्रैगन हो।" यहां विवरण पढ़ें: http://www.gotw.ca/publications/advice97.htm –

3

जब मुझे मूल को प्रभावित किए बिना डुप्लिकेट को संशोधित करने के लिए कुछ डुप्लिकेट करने की आवश्यकता होती है, और निश्चित रूप से इस परिदृश्य में गहरी क्लोनिंग (केवल) पर्याप्त होगी। मुझे इसे एक ऐसे सिस्टम पर करना पड़ा जहां मैं एक डोमेन क्लास इंस्टेंस क्लोन करूँगा, उपयोगकर्ता के परिवर्तनों को लागू करूंगा, और उसके बाद उपयोगकर्ता के परिवर्तनों को सत्यापित करने के लिए दोनों की तुलना करें।

2

ऑब्जेक्ट.क्लोन() विधि निर्दिष्ट नहीं करता है कि सबक्लास की प्रति गहरी या उथली प्रतिलिपि है, यह पूरी तरह से विशिष्ट वर्ग पर निर्भर है। ऑब्जेक्ट.क्लोन() विधि स्वयं एक उथली प्रतिलिपि (ऑब्जेक्ट क्लास की आंतरिक स्थिति की प्रतिलिपि बनाता है), लेकिन उप-वर्गों को इसे ओवरराइड करना होगा, super.clone() को कॉल करना होगा, और आवश्यकतानुसार अपनी आंतरिक स्थिति की प्रतिलिपि बनाना चाहिए (उथला या गहरा)।

यह कुछ सम्मेलनों को निर्दिष्ट करता है, जिन्हें आप अनुसरण कर सकते हैं या नहीं। के लिए (a.getClass() == a.clone()। GetClass()) सत्य वापस करने के लिए, super.clone() को केवल 'नया सबक्लास()' के बजाय बुलाया जाना चाहिए, क्योंकि super.clone() संभवत: सही ढंग से सही होगा इस ऑब्जेक्ट की कक्षा को तुरंत चालू करें (यहां तक ​​कि उप-वर्गों में), और निजी क्षेत्र समेत सभी आंतरिक राज्यों की प्रतिलिपि बनाएँ, जिन्हें कॉपी प्रतिलिपि, उचित दृश्यता नियमों का उपयोग करके सबक्लास द्वारा कॉपी नहीं किया जा सका। या बेहतर encapsulation के लिए, आपको एक ऐसे कन्स्ट्रक्टर का पर्दाफाश करने के लिए मजबूर होना चाहिए जिसे प्रकट नहीं किया जाना चाहिए।

उदाहरण:

//simple clone 
class A implements Cloneable { 
    private int value; 
    public A clone() { 
    try { 
     A copy = (A) super.clone(); 
     copy.value = this.value; 
     return copy; 
    } catch (CloneNotSupportedException ex) {} 
    } 
} 

//clone with deep and shallow copying 
class B extends A { 
    Calendar date; 
    Date date; 
    public B clone() { 
    B copy = (B) super.clone(); 
    copy.date = (Calendar) this.date.clone(); // clones the object 
    copy.date = this.date; // copies the reference 
    return copy; 
    } 
} 

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

जब निर्भर वस्तुएं अपरिवर्तनीय (दिनांक की तरह) होती हैं, तो वही उदाहरण साझा करना आम तौर पर कोई मुद्दा नहीं है, और एक उथली प्रति पर्याप्त हो सकती है।

ऑब्जेक्ट.क्लोन() का उपयोग करते समय आपको कुछ नियमों का पालन करना होगा, लेकिन वे समझने योग्य होने के लिए काफी सरल हैं। शायद सबसे मुश्किल हिस्सा सही ढंग से परिभाषित कर रहा है कि आपको अपने ऑब्जेक्ट ग्राफ़ में कितनी गहरी प्रतिलिपि बनाना चाहिए। एक तार्किक मुद्दा, एक भाषा मुद्दा नहीं, जो है।

0

मैंने ऑब्जेक्ट का उपयोग किया है।स्प्रिंग वेबफ्लो एप्लिकेशन में क्लोन() यह जांचने के लिए कि क्या उपयोगकर्ता बदलता है जब उपयोगकर्ता ऑडिटिंग उद्देश्यों के लिए किसी फॉर्म पर डेटा संपादित/दर्ज करता है।

प्रवाह की शुरुआत में, मैं क्लोन विधि है जो प्रपत्र समर्थन वसंत webflow में इस्तेमाल वस्तु पर लागू किया और उपयोगकर्ता सत्र को क्लोन के कहने को बचाने गया था कहते हैं। एक बार जब उपयोगकर्ता ने एचटीएमएल फॉर्म पर संपादन डेटा पूरा कर लिया है और सेव बटन दबाया है तो मैं बैकिंग ऑब्जेक्ट को बैक ऑब्जेक्ट से जुड़े नए मानों की तुलना क्लोन वैल्यू से तुलना करता हूं ताकि यह निर्धारित किया जा सके कि उपयोगकर्ता किस डेटा को बदल चुका है।

यह अच्छी तरह से काम किया है और लागू करने के लिए वास्तव में आसान था, मैं वास्तव में जावा में क्लोनिंग कोई समस्या नहीं किया है।

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