2013-02-28 6 views
9

मैं एक अंतिम वर्ग NameAndValue हो रहा है। मैं System.arrayCopy() का उपयोग कर NameAndValue वस्तुओं की एक सरणी की नकल की और जब मैं की नकल की सरणी में एक NameAndValue वस्तु बदल गया है, यह मूल सरणी में परावर्तित होती है।System.arrayCopy() वस्तु ऑब्जेक्ट या ऑब्जेक्ट का संदर्भ देता है?

public final class NameAndValue 
{ 
    public String name; 
    public String value; 

    public NameAndValue() 
    { 

    } 

    public NameAndValue(String name,String value) 
    { 
     this.name = name; 
     this.value = value; 
    } 
} 

public class Main 
{ 
    public static void main(String[] args) 
    { 
     NameAndValue[] nv = new NameAndValue[4]; 
     nv[0] = new NameAndValue("A", "1"); 
     nv[1] = new NameAndValue("B", "2"); 
     nv[2] = new NameAndValue("C", "3"); 
     nv[3] = new NameAndValue("D", "4"); 

     NameAndValue[] nv2 = new NameAndValue[4]; 
     System.arraycopy(nv, 0, nv2, 0, 2); 
     nv2[2] = new NameAndValue("Y","25"); 
     nv2[3] = new NameAndValue("Z","26"); 

     for (int i = 0; i < 2; i++) 
     { 
      NameAndValue[] nv3 = new NameAndValue[4]; 
      System.arraycopy(nv2, 0, nv3, 0, 4); 
      nv3[2].value = String.valueOf(i); 
      nv3[3].value = String.valueOf(i+1); 

      System.out.println(nv2[2].value); 
      System.out.println(nv2[3].value); 
      System.out.println("-----------------------"); 
     } 
    } 
} 

मैं के रूप में उत्पादन हो रही है,

0 
1 
----------------------- 
1 
2 
----------------------- 

मैं 25 और सभी मामलों में 26 के रूप में उत्पादन मिल गया है चाहिए, सही ?? यह क्यों बदल जाता है ??

उत्तर

18

System.arrayCopy() वस्तु ऑब्जेक्ट या ऑब्जेक्ट का संदर्भ देता है?

संदर्भ, यह एक उथले प्रतिलिपि है। हैरानी की बात है, the docs don't say that explicitly, बस परोक्ष रूप में वे केवल सरणी तत्वों को कॉपी, रिकर्सिवली नहीं बातें वे संदर्भ कॉपी करने के बारे में बात करते हैं

यह बिल्कुल वैसा ही है जैसे कि आप इस के लिए किया था:

NameAndValue nv1 = new NameAndValue("A", "1"); 
NameAndValue nv2 = nv1; 
nv2.value = "4"; 
System.out.println(nv1.value); // 4 

प्रत्येक सरणी तत्व nv1 की तरह है और nv2 ऊपर वार्स। nv1 और nv2 संदर्भ (बिंदु) को एक ही अंतर्निहित वस्तु के रूप में, इसलिए सरणी प्रविष्टियां करें, जिनमें उन प्रविष्टियों को एक सरणी से दूसरे में कॉपी किया गया है।

+1

मैं बहुत कुछ (कोर जावा एपीआई और विभिन्न लोकप्रिय पुस्तकालयों में) मिल गया है जो उथले प्रतियां वास्तव में दस्तावेज़ों में स्पष्ट रूप से यह नहीं बताती हैं - मुझे लगता है कि यह "उथले मान लीजिए जब तक कि अन्यथा नहीं कहा जाता"। – berry120

+0

@ बेरी 120: हाँ। और यह एक उचित धारणा बनाने के लिए है। मैंने इसे स्पष्ट कर दिया है, लेकिन मुझे लगता है कि ब्रेवटी में कुछ मूल्य है।:-) –

+0

ओह सहमत हो गया, मैं बस इसे इंगित कर रहा था :-) – berry120

2

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

इस अर्थ में, यह संदर्भ द्वारा सख्ती से गुजरने के बजाय "मूल्य द्वारा संदर्भ" पास है - लेकिन जो प्रभाव आप देख रहे हैं वह है क्योंकि संदर्भ वही रहता है।

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

1

जहाँ तक मुझे पता है arraycopy एक उथली प्रतिलिपि है। जिसका अर्थ है कि नई सरणी पुरानी सरणी में तत्वों के पते के संदर्भ में होगी। इसलिए यदि आप उनमें से किसी एक में मूल्य समायोजित करते हैं, तो यह

1

सिस्टम.एरेकॉपी दोनों एक उथली प्रतिलिपि पर प्रतिबिंबित होगा। यहां बताया गया है:

यह जेएनआई का उपयोग करता है जैसे कि memcpy() जो कि पॉइंटर्स को स्मृति में कॉपी करता है। यह एक बहुत तेज़ ऑपरेशन है।

0
int[] a = {1, 2, 3}; 
    int[] b = new int[3]; 
    System.arraycopy(a, 0, b, 0, 3); 
    b[1] = 0; 
    System.out.println(Arrays.toString(b)); 
    System.out.println(Arrays.toString(a)); 

उत्पादन इस तरह है: [1, 0, 3] [1, 2, 3]

+0

यह सिर्फ दिखाता है कि यह एक उथली प्रतिलिपि करता है। आपकी संरचना में कोई गहराई नहीं है। यदि इसकी गहराई है, तो आप पाएंगे कि 'System.arraycopy' एक गहरी प्रति नहीं करता है। –

+0

हाँ, आप सही हैं। मैंने एक सरणी तत्व के संदर्भ को बदलने का परीक्षण नहीं किया, इसके बजाय, मैंने संदर्भित डेटा की सामग्री को बदल दिया। मैंने पाया कि ये 2 सरणी मान समान हैं। thks! –

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

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