2015-11-02 3 views
19

मैं समझता हूं कि जावा क्लोनिंग कैसे काम करती है और इसका उपयोग करने के खिलाफ तर्क। आइए कहें कि मैं इसे किसी भी तरह इस्तेमाल करने के लिए तैयार हूं।ओवरराइड के अंदर क्यों नहीं डाला गया। क्लोन?

सुविधा के मैं इस प्रकार वर्ग फू के लिए एक क्लोन विधि लिखने के लिए चाहते हैं के लिए:

@Override 
public Foo clone(){ 
    Foo f = (Foo)super.clone(); 
    //Replace mutable fields 
    return f; 
} 

जहाँ तक मुझे इस बता सुरक्षित होगा कर सकते हैं। हालांकि, मैंने देखा कि एपीआई में क्लोनेबल कक्षाएं ऐसा नहीं करती हैं। क्या इसका कोई कारण है और क्या यह खराब शैली है?

+1

ध्यान दें कि यह केवल तभी उपयोगी है जब आप इसे इस तरह उपयोग करते हैं: 'Foo foo = ...; फू बार = foo.clone() '। – biziclop

उत्तर

17

जावा 5 से पहले वापस, कॉन्वर्सेंट रिटर्न प्रकारों की अनुमति नहीं थी, इसलिए Foo clone() संकलित भी नहीं होगा। चूंकि बहुत से Cloneable कक्षाएं बहुत समय पहले लिखी गई हैं, शायद यह ज्यादातर मामलों का कारण है।

मुझे संदेह है कि नए वर्ग इसका उपयोग नहीं करते हैं क्योंकि clone() काफी मुट्ठी भर माना जाता है, और जब लोग शायद ही कभी इसका उपयोग करते हैं, तो वे यह भी नहीं सोचते कि वे इसे कास्ट कर सकते हैं। उन्हें कुछ "क्लोन()" प्रश्न को कार्यान्वित करने और पुराने तरीके से कोड लिखने के लिए कुछ मिलता है।

+5

अच्छा पुराना "यह इतना तोड़ दिया है कि कभी भी इसे ठीक करने की कोशिश करने में समय बर्बाद करने की कोशिश नहीं की गई"। – mgarciaisaia

3

Object.clone() एक नई वस्तु बनाता है जहां सभी फ़ील्ड मूल के समान मूल्य होते हैं। संदर्भ प्रकार के क्षेत्रों के लिए, इसका मतलब है कि नया क्षेत्र मूल रूप से उसी वस्तु का संदर्भ है। यह clone फ़ील्ड नहीं है। इसलिए कई मामलों में, डिफ़ॉल्ट कार्यान्वयन साझा डेटा का कारण बनता है, जो अवांछित हो सकता है। उदाहरण के लिए, यदि ArrayList.clone() ने डिफ़ॉल्ट कार्यान्वयन का उपयोग किया है, तो आप एक ही बैकिंग सरणी साझा करने वाले दो ArrayList उदाहरणों के साथ समाप्त हो जाएंगे।

यदि किसी ऑब्जेक्ट के सभी फ़ील्ड अपरिवर्तनीय हैं, तो उचित प्रकार के लिए super.clone() का परिणाम डालना एक अच्छा विचार हो सकता है।

+1

एपीआई काफी स्पष्ट है कि 'क्लोन()' क्या करने की उम्मीद है, लेकिन यह कहता है: 'आमतौर पर, इसका अर्थ यह है कि किसी भी उत्परिवर्तनीय वस्तुओं की प्रतिलिपि बनाना जिसमें ऑब्जेक्ट की आंतरिक "गहरी संरचना" शामिल है और संदर्भों को प्रतिस्थापित किया गया है इन वस्तुओं को प्रतियों के संदर्भ के साथ। ', इसलिए' क्लोन() 'आदर्श रूप से एक गहरी प्रतिलिपि वापस करनी चाहिए। आदर्श रूप से लेकिन जरूरी नहीं ... – biziclop

+0

यदि खेतों में सभी अपरिवर्तनीय हैं, तो गहरी और उथली प्रतिलिपि के बीच कोई अंतर नहीं है। –

+3

यह सच है लेकिन सवाल से संबंधित कैसे है? मैं थोड़ा खो गया हूँ। :) – biziclop

3

हम्म, यह वास्तव में एक खराब शैली नहीं है, वास्तव में यह बेहतर है कि आप जावा 1.5 के रिलीज के बाद से ऐसा करते हैं, क्योंकि कॉन्वर्सेंट रिटर्न प्रकार जेनिक्स के हिस्से के रूप में रिलीज 1.5 में पेश किए गए थे, और ऐसा करके, आप आपके एपीआई को उपयोग करना आसान बनाता है (कोई कास्टिंग आवश्यक नहीं होगा)।

स्रोत (प्रभावी जावा 2 संस्करण)।

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