दिलचस्प पोस्ट
'टाइपिड' बनाम 'टाइपफ' में सी ++ फायरबग का उपयोग करते हुए जावा स्क्रिप्ट में मेमोरी लीक ढूँढना? एक आंकड़े में एकाधिक भूखंड Levenshtein दूरी की गणना करने के लिए सबसे कारगर तरीका विज़ुअल स्टूडियो 2015 में एक साझा परियोजना और कक्षा पुस्तकालय में क्या अंतर है? जब उपयोगकर्ता बाउंस से बाहर की ओर स्वाइप करने की कोशिश कर रहा है, तो ViewPager पता लगाता है जावास्क्रिप्ट ऑब्जेक्ट डिस्ट्रक्चरिंग और अलियासिंग एंड्रॉइड जीओकोडर "सेवा उपलब्ध नहीं" अपवाद फेंकने क्यों है? सी # वस्तु के लिए JSON स्ट्रिंग कन्वर्ट एंड्रॉइड में दो स्थानों के बीच की दूरी क्या है? सरल जावास्क्रिप्ट सरणी प्रारंभिक क्रोम में काम नहीं कर रहा है कैसे JTextField में वर्णों की संख्या को सीमित करने के लिए? कैसे iPhone / iPad डिवाइस पर कुल उपलब्ध / मुक्त डिस्क स्थान का पता लगाने के लिए? एक्लिप्स सीडीटी इंडेक्सर को सी ++ 11 कंटेनर नहीं पता है SQL सर्वर कटौती और 8192 की सीमा

गहरी प्रतिलिपि, उथले प्रतिलिपि, क्लोन

संभव डुप्लिकेट:
मैं जावा में किसी ऑब्जेक्ट की प्रतिलिपि कैसे करूं?

मुझे गहरी प्रतिलिपि, उथले प्रतिलिपि और जावा में क्लोन के बीच अंतर पर स्पष्टीकरण की आवश्यकता है

Solutions Collecting From Web of "गहरी प्रतिलिपि, उथले प्रतिलिपि, क्लोन"

दुर्भाग्य से, "उथले प्रतिलिपि", "गहरी प्रतिलिपि" और "क्लोन" सभी बल्कि बीमार परिभाषित शब्द हैं।


जावा के संदर्भ में, हमें सबसे पहले "एक मूल्य कॉपी करना" और "एक वस्तु की नकल" के बीच भेद करना चाहिए।

int a = 1; int b = a; // copying a value int[] s = new int[]{42}; int[] t = s; // copying a value (the object reference for the array above) StringBuffer sb = new StringBuffer("Hi mom"); // copying an object. StringBuffer sb2 = new StringBuffer(sb); 

संक्षेप में, एक वेरिएबल के संदर्भ के एक असाइनमेंट जिसका प्रकार एक संदर्भ प्रकार है "एक मूल्य कॉपी करना" जहां मूल्य ऑब्जेक्ट संदर्भ है किसी ऑब्जेक्ट की प्रतिलिपि बनाने के लिए, कुछ को new या तो स्पष्ट रूप से या हुड के नीचे उपयोग करने की आवश्यकता है


अब वस्तुओं की "गहरी" प्रतिलिपि बनाम "उथले" बनाम उथला प्रतिलिपि आम तौर पर एक वस्तु के केवल एक स्तर की प्रतिलिपि बनाने का मतलब है, जबकि गहरी नकल का आम तौर पर एक से अधिक स्तर प्रतिलिपि बनाने का अर्थ है। समस्या यह तय करने में है कि हमें एक स्तर से क्या मतलब है। इस पर विचार करो:

 public class Example { public int foo; public int[] bar; public Example() { }; public Example(int foo, int[] bar) { this.foo = foo; this.bar = bar; }; } Example eg1 = new Example(1, new int[]{1, 2}); Example eg2 = ... 

सामान्य व्याख्या यह है कि Example 1 की " eg1 " की प्रतिलिपि एक नया Example ऑब्जेक्ट होगा जिसका foo 1 के बराबर होता है और जिनकी bar फ़ील्ड मूल के रूप में उसी सरणी से संदर्भित होती है; जैसे

 Example eg2 = new Example(eg1.foo, eg1.bar); 

Example 1 की "गहरी" प्रतिलिपि की सामान्य व्याख्या एक नया Example ऑब्जेक्ट होगा जिसका foo 1 के बराबर होगा और जिनकी bar फ़ील्ड मूल सरणी की एक प्रति को संदर्भित करता है; जैसे

 Example eg2 = new Example(eg1.foo, Arrays.copy(eg1.bar)); 

(सी / सी + + पृष्ठभूमि से आने वाले लोग कह सकते हैं कि एक संदर्भ असाइन एक उथले प्रतिलिपि उत्पन्न करता है। हालांकि, जावा संदर्भ में उथले प्रतिलिपि से हम सामान्य रूप से इसका अर्थ नहीं करते हैं …)

अनिश्चितता के दो और प्रश्न / क्षेत्र मौजूद हैं:

  • गहरी कैसे गहरी है? क्या यह दो स्तरों पर बंद हो जाता है? तीन स्तर? क्या इसका अर्थ जुड़ा हुआ ऑब्जेक्ट का पूरा ग्राफ़ है?

  • समरूप डेटा प्रकारों के बारे में क्या; जैसे एक स्ट्रिंग? एक स्ट्रिंग वास्तव में सिर्फ एक ऑब्जेक्ट नहीं है वास्तव में, यह कुछ स्केलर फ़ील्ड्स के साथ एक "ऑब्जेक्ट" है, और वर्णों के सरणी के लिए एक संदर्भ है। हालांकि, एआरपी पूरी तरह से एपीआई से छिपा हुआ है। इसलिए, जब हम एक स्ट्रिंग की प्रतिलिपि बनाने की बात करते हैं, तो क्या इसे एक "उथल" प्रति या "गहरी" प्रतिलिपि कहते हैं? या हमें इसे एक कॉपी कह देना चाहिए?


अंत में, क्लोन क्लोन एक ऐसा तरीका है जो सभी वर्गों (और सरणियों) पर मौजूद होता है जो आम तौर पर लक्ष्य वस्तु की एक प्रति का उत्पादन करने के लिए सोचा जाता है। तथापि:

  • इस पद्धति का विनिर्देश जानबूझकर यह नहीं कहता कि यह एक उथले या गहरी प्रतिलिपि है (यह मानते हुए कि एक अर्थपूर्ण अंतर है)।

  • वास्तव में, विनिर्देश यह विशेष रूप से नहीं बताता है कि क्लोन एक नया ऑब्जेक्ट पैदा करता है।

ये जवादाक कहता है:

"इस ऑब्जेक्ट की प्रतिलिपि बनाता है और रिटर्न करता है।" कॉपी "का सटीक अर्थ ऑब्जेक्ट के वर्ग पर निर्भर हो सकता है। सामान्य उद्देश्य यह है कि, किसी भी ऑब्जेक्ट x के लिए, अभिव्यक्ति x.clone() != x सच हो जाएगा , और अभिव्यक्ति x.clone().getClass() == x.getClass() सही होंगे, लेकिन ये पूर्ण आवश्यकताएं नहीं हैं। जबकि यह आमतौर पर मामला है x.clone().equals(x) होगा सच हो, यह एक पूर्ण आवश्यकता नहीं है। "

ध्यान दें, यह कह रहा है कि एक चरम पर क्लोन लक्ष्य वस्तु हो सकता है, और दूसरी चरम पर क्लोन मूल के बराबर नहीं हो सकता । और यह मानता है कि क्लोन भी समर्थित है।

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


कुछ लोग तर्क देते हैं (जैसा @ सुपरकॉटेंट टिप्पणी करता है) कि जावा clone() विधि टूट जाती है। लेकिन मुझे लगता है कि सही निष्कर्ष यह है कि ओ ओ के संदर्भ में क्लोन की अवधारणा टूट गई है। AFAIK, क्लोनिंग का एक एकीकृत मॉडल विकसित करना असंभव है जो सभी ऑब्जेक्ट प्रकारों में संगत और प्रयोग करने योग्य है।

शब्द "क्लोन" अस्पष्ट है (हालांकि जावा क्लास लाइब्रेरी में क्लोन करने योग्य इंटरफ़ेस शामिल है) और एक गहरी कॉपी या उथले प्रति का उल्लेख कर सकते हैं। दीप / उथले प्रतियां विशेष रूप से जावा से नहीं जुड़ी हैं लेकिन एक वस्तु की प्रतिलिपि बनाने से संबंधित एक सामान्य अवधारणा है, और यह भी दर्शाती है कि ऑब्जेक्ट के सदस्यों को भी कैसे कॉपी किया गया है।

उदाहरण के तौर पर, मान लें कि आपके पास एक व्यक्ति वर्ग है:

 class Person { String name; List<String> emailAddresses } 

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

एक गहरी प्रति का मतलब है कि आप प्रत्येक सदस्य को लगातार प्रतिलिपि बनाते हैं, इसलिए आपको नए Person लिए एक नई List बनाने की आवश्यकता होगी, और तब सामग्री को पुराने से नए ऑब्जेक्ट में कॉपी करनी होगी।

यद्यपि उपर्युक्त उदाहरण तुच्छ है, हालांकि गहरी और उथले प्रतियों के बीच अंतर महत्वपूर्ण है और इसका किसी भी आवेदन पर एक बड़ा प्रभाव पड़ता है, खासकर यदि आप बिना किसी सामान्य क्लॉन विधि को पहले से तैयार करने का प्रयास कर रहे हैं, यह जानने के बाद कि यह किसी व्यक्ति को बाद में इसका उपयोग कैसे कर सकता है। ऐसे समय होते हैं जब आपको गहरे या उथले शब्दों की ज़रूरत होती है, या कुछ हाइब्रिड जहां आप कुछ सदस्यों की गहरी प्रतिलिपि करते हैं लेकिन अन्य नहीं।

  • गहरी प्रतिलिपि: इस ऑब्जेक्ट को क्लोन करें और प्रत्येक अन्य ऑब्जेक्ट के संदर्भ में यह है
  • उथला प्रतिलिपि: इस वस्तु को क्लोन करें और उसके संदर्भों को रखें
  • वस्तु क्लोन () फेंकता है CloneNotSupportedException: यह निर्दिष्ट नहीं किया जाता है कि यह एक गहरी या उथले प्रतिलिपि वापस करनी चाहिए, लेकिन बहुत कम से कम: o.clone ()! = O

एक उथले प्रति एक मौजूदा ऑब्जेक्ट के दूसरे संदर्भ से ज्यादा कुछ नहीं है। आपके द्वारा उथले प्रतिलिपि में किए गए कोई भी बदलाव उस वस्तु के अन्य संदर्भों (और महसूस किए गए) के द्वारा देखा जाता है निम्नलिखित कोड पर विचार करें:

  List<Integer> listA, listB; listA = new ArrayList<>(); listA.add(new Integer(1)); listB = listA; listB.add(new Integer(2)); 

कथन: listB = listA सूची B को सूची A की "उथले प्रतिलिपि" बनाता है , और दोनों चर समान सूची का संदर्भ देते हैं। बयान के बाद: listB.add (नई पूर्णांक (2)); , listB (अधिक विशेष रूप से, सूची जो listB संदर्भ) में दो तत्व हैं, (1 और 2)। हालांकि, जब सूची भी इसी सूची का संदर्भ देता है, तो इसमें भी दो तत्व शामिल होते हैं

जावा में, गहरी प्रति के लिए कोई सटीक परिभाषा नहीं है । एक इंटरफ़ेस है जो एक डेवलपर को परिभाषित करता है कि क्लोन का क्या मतलब है, लेकिन यह डेवलपर की सनक पर निर्भर है। गहरी प्रतिलिपि और क्लोन यह दर्शाते हैं कि किसी ऑब्जेक्ट के संदर्भ के बजाय, आप पूरी तरह से अलग, अलग ऑब्जेक्ट प्राप्त कर रहे हैं।

उपरोक्त कोड नमूने पर विचार करें। एक गहरी प्रति (या क्लोन) के साथ, सूची और listB एक-दूसरे से अलग हो जाएगा (यानी, वे अलग-अलग आइटम का संदर्भ लेंगे) इसलिए, एक गहरी कॉपी या क्लोन के लिए , listB.add () सूची सूची को प्रभावित नहीं करेगा। यह है, सूची में अब भी एक तत्व (1) होगा, और listB में दो तत्व (1 और 2) होंगे।

काश, यह या मामला नहीं हो सकता है। एक इंटरफ़ेस ( क्लोन करने योग्य ) है जो उस तरीके को निर्दिष्ट करता है कि क्लोन करने योग्य ऑब्जेक्ट का क्लोन बनाया गया है। यह कैसे गहरा जाता है उस वर्ग पर निर्भर करता है जो वर्ग को परिभाषित और कार्यान्वित करता है जो एक क्लोन का गठन करता है। किसी ऑब्जेक्ट के गहरे या उथले प्रतियां बनाने के बारे में फैसला करना एक तुच्छ निर्णय नहीं है। ऐसे कुछ ऑब्जेक्ट हैं जहां एक गहरी कॉपी बनाने से कोई मतलब नहीं है (जैसे कि सिंगलटन के संदर्भ), या कुशल नहीं हैं (जैसे कि एक स्थिर की प्रतिलिपि, जैसे स्ट्रिंग)

यह संबंधित स्टैक ऑवरफ्लो लेख देखें , या यह एक

शब्द "उथले प्रतिलिपि" और "गहरी कॉपी" थोड़ा अस्पष्ट हैं; मैं "सदस्यीय क्लोन" शब्द का उपयोग करने का सुझाव दूंगा और मैं "सिमेंटिक क्लोन" कहूँगा। ऑब्जेक्ट का एक "सदस्यवृत्त क्लोन" एक नया ऑब्जेक्ट है, मूल के रूप में एक ही रन-टाइम प्रकार की, प्रत्येक फ़ील्ड के लिए, सिस्टम प्रभावी रूप से "newObject.field = oldObject.field" करता है। आधार ऑब्जेक्ट। क्लोन () एक सदस्यीय क्लोन करता है; सदस्यवृत्त क्लोनिंग आम तौर पर किसी वस्तु को क्लोन करने के लिए सही प्रारंभ बिंदु होता है , लेकिन ज्यादातर मामलों में किसी सदस्य के क्लोन के बाद कुछ "फिक्सअप काम" की आवश्यकता होगी बिना किसी आवश्यक फ़िक्सअप के निष्पादन के बावजूद सदस्यत्व वाले क्लोन के माध्यम से तैयार किए गए किसी वस्तु का उपयोग करने के कई मामलों में बुरी चीजें होती हैं, जिसमें वस्तु का भ्रष्टाचार भी शामिल है जिसमें क्लोन किया गया था और संभवतः अन्य वस्तुएं भी थीं कुछ लोग "उथले क्लोनिंग" शब्द का उपयोग सदस्यीय क्लोनिंग के संदर्भ में करते हैं, लेकिन यह शब्द का एकमात्र उपयोग नहीं है।

एक "अर्थ क्लोन" एक वस्तु है जिसमें मूल के समान डेटा होता है, प्रकार के दृश्य के बिंदु से । जांच के लिए, एक बिगलिस्ट पर विचार करें जिसमें एक अर्रे और गिनती शामिल है इस तरह के ऑब्जेक्ट का अर्थ-स्तरीय क्लोन एक सदस्यत्व वाला क्लोन करेगा, फिर ऐरे की जगह> एक नई सरणी के साथ, नए नेस्टेड एरे बनायें, और टी के सभी मूल एरे से नए लोगों को कॉपी करें। यह टी खुद की किसी भी तरह की गहरी क्लोनिंग का प्रयास नहीं करेगा । विडंबना यह है कि, कुछ लोग क्लोनिंग "उथले क्लोनिंग" का उल्लेख करते हैं, जबकि अन्य इसे "गहरे क्लोनिंग" कहते हैं। वास्तव में उपयोगी शब्दावली नहीं है

जहां ऐसे मामले हैं जहां वास्तव में गहरे क्लोनिंग (सभी म्यूटटेबल प्रकारों की पुन: प्रतिलिपि बनाते हैं) उपयोगी है, यह केवल ऐसे प्रकार के द्वारा किया जाना चाहिए जिनके घटक ऐसे आर्किटेक्चर के लिए डिज़ाइन किए गए हैं। कई मामलों में, वास्तव में गहरे क्लोनिंग अत्यधिक है, और यह उन परिस्थितियों में हस्तक्षेप कर सकता है जहां की जरूरत है, वास्तव में एक वस्तु है जिसका दृश्य सामग्री एक ही वस्तुओं को दूसरे (अर्थात अर्थ-स्तर की प्रतिलिपि) के रूप में दर्शाती है। ऐसे मामलों में जहां किसी ऑब्जेक्ट की दृश्य सामग्री लगातार दूसरे ऑब्जेक्ट से प्राप्त होती है, अर्थ-स्तरीय क्लोन एक पुनरावर्ती गहरी क्लोन का अर्थ होता है, लेकिन ऐसे मामलों में जहां दृश्य सामग्री केवल कुछ सामान्य प्रकार होती है, कोड को आँख बंद करके सब कुछ गहराई से नहीं करना चाहिए ऐसा लगता है कि यह संभवतः गहरा क्लोन-सक्षम हो सकता है