2011-06-17 14 views
9

जैसा कि मैंने समझा, विधि clone() हमें जावा में ऑब्जेक्ट (कोई refernce) कॉपी करने की क्षमता देता है। लेकिन मैंने यह भी पढ़ा कि प्रतिलिपि उथला है। तो क्या बात है? clone() विधि मुझे कौन सा क्षमता देता है, कि एक सरल आकलन नहीं करता है?जावा में क्लोन() विधि

उत्तर

21

अंतर यह है कि आप मूल वस्तु को संशोधित किए बिना क्लोन ऑब्जेक्ट को संशोधित कर सकते हैं।

Point p = new Point(1,2); 
Point p2 = p.clone(); 
Point p3 = p; 
p2.x = 5; 
p3.y = 7; 

p3 पर परिवर्तन, वापस p को खिलाने जबकि p2 पर परिवर्तन नहीं करता है।

देखें कि स्थिति अलग-अलग बयान (यह मानते हुए 1 वस्तुओं, 2, 5, 7 होगा) के बाद है दो:

Point p = new Point(1,2); 

      .-----. .-----. 
p -----> | x -+--> | 1 | 
      |  | '-----' 
      |  | .-----. 
      | y -+--> | 2 | 
      '-----' '-----' 


Point p2 = p.clone(); 

      .-----. .-----. .-----. 
p -----> | x -+--> | 1 | <--+- x | <----- p2 
      |  | '-----' |  | 
      |  | .-----. |  | 
      | y -+--> | 2 | <--+- y | 
      '-----' '-----' '-----' 

Point p3 = p; 

      .-----. .-----. .-----. 
p -----> | x -+--> | 1 | <--+- x | <----- p2 
      |  | '-----' |  | 
      |  | .-----. |  | 
p3 -----> | y -+--> | 2 | <--+- y | 
      '-----' '-----' '-----' 


p2.x = 5; 

      .-----. .-----. .-----. .-----. 
p -----> | x -+--> | 1 | | x -+--> | 5 | 
      |  | '-----' |  | '-----' 
      |  | .-----. |  | 
p3 -----> | y -+--> | 2 | <--+- y | <----- p2 
      '-----' '-----' '-----' 


p3.y = 7; 

      .-----. .-----. .-----. .-----. 
p -----> | x -+--> | 1 | | x -+--> | 5 | 
      |  | '-----' |  | '-----' 
      |  | .-----. |  | 
p3 -----> | y | | 2 | <--+- y | <----- p2 
      '--+--' '-----' '-----' 
       |  .-----. 
       '---> | 7 | 
        '-----' 
+0

धन्यवाद, लेकिन मुझे नहीं पता कि क्यों p2.x पी में कुछ भी नहीं बदलेगा। यह सही है कि हमारे पास 2 diffrents ऑब्जेक्ट्स हैं, लेकिन वे एक ही एक्स और वाई (क्योंकि उथली प्रतिलिपि) के लिए अंक हैं। मैं क्या खो रहा हूँ? – Tom

+0

असाइनमेंट (पिछले दो पंक्तियों में) क्या बदलता है 'x' और 'y' बिंदु। यहां तक ​​कि यदि 'p.x' और 'p2.x' का एक ही मान है (उसी ऑब्जेक्ट का जिक्र करते हुए), वे अलग-अलग चर हैं, और किसी को असाइन करने से दूसरे को नहीं बदला जाता है। (इस मामले में वे ऑब्जेक्ट्स भी नहीं हैं, लेकिन आदिम मूल्य हैं, लेकिन यदि वे ऑब्जेक्ट्स थे तो वही बात मान्य होगी।) –

+0

इस उदाहरण में हम उथले और गहरे क्लोनिंग के बीच का अंतर नहीं देखते हैं। –

4

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

7

एक असाइनमेंट एक चर के लिए एक उदाहरण के संदर्भ की प्रतिलिपि बनाता है। क्लोन ऑपरेशन उदाहरण क्लोन करेगा (और क्लोन के संदर्भ को असाइन करेगा)।

काम के साथ, आप कई के साथ चर के एक वस्तु की ओर इशारा करते, क्लोनिंग आप कई चर कई वस्तुओं के संदर्भ पकड़ होगा के साथ समाप्त होगा।

SomeCloneable a = new SomeCloneable(); 
SomeCloneable b = a;      // a and b point to the same object 

/* versus */ 

SomeCloneable a = new SomeCloneable(); 
SomeCloneable b = a.clone();    // a and b point to the different objects 
+0

'' Cloneable' क्लोन नहीं है() 'विधि सार्वजनिक करने के लिए है, हालांकि। आपको अपने 'ए' और 'बी' को' कुछ क्लोनेबल 'घोषित करना होगा। –

+0

@ पालो एबरमान - अच्छा पकड़, धन्यवाद, मैं इसे सही कर दूंगा! –

3

उथला प्रति वस्तु के लिए डिफ़ॉल्ट है। आप एक गहरी प्रतिलिपि करने के लिए क्लोन ओवरराइड कर सकते हैं।

1

गहराई में क्लोन करने के लिए आप Cloneable को लागू करने और ओवरराइड क्लोन()

public class MyClass implements Cloneable { 

private Object attr = new Object(); 

@Override 
public Object clone() throws CloneNotSupportedException { 
    MyClass clone = (MyClass)super.clone(); 
    clone.attr = new Object(); 
    return clone; 
} 

@Override 
public String toString() { 
    return super.toString()+", attr=" + attr; 
} 

public static void main(String[] args) throws Exception { 
    MyClass x = new MyClass(); 
    System.out.println("X="+x); 
    MyClass y = (MyClass)x.clone(); 
    System.out.println("Y="+y); 
} 

}

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