जैसा कि अन्य ने कहा, जब तक कि यह एक आदिम प्रकार न हो, आपको वस्तु का संदर्भ मिलता है। यह सी ++ में पॉइंटर के समान है, यह आपको ऑब्जेक्ट तक पहुंचने की अनुमति देता है, लेकिन सी ++ संदर्भ (एक चर के मेमोरी एड्रेस पर पॉइंटर) के विपरीत यह आपको किसी अन्य ऑब्जेक्ट से प्रतिस्थापित करने की अनुमति नहीं देता है। केवल सेटटर ही ऐसा कर सकता है।
मुझे आपके प्रश्न में दो प्रकार दिखाई देते हैं, test.getArray().remove(0)
और aVar.remove(0)
। उन परिणामों के परिणाम में कोई अंतर नहीं है, यह अभी भी कुछ सूचक-जैसा संदर्भ है और यह मूल को संशोधित करता है।
आपको कभी भी गेटर को कॉल करके क्लोन नहीं मिलता है, इसलिए जब तक ऑब्जेक्ट अपरिवर्तनीय न हो, तो आप उस ऑब्जेक्ट को संशोधित कर सकते हैं जिस पर गेटटर ने आपको पहुंच प्रदान की है। उदाहरण के लिए, String
अपरिवर्तनीय है, कोई भी मूल Collection
(ArrayList
समेत) उत्परिवर्तनीय है। संग्रह को अपरिवर्तनीय बनाने के लिए आप Collections.unmodifiable*(...)
पर कॉल कर सकते हैं। हालांकि, अगर संग्रह की वस्तुएं उत्परिवर्तनीय हैं, तो भी वे बदल सकते हैं।
कुछ मामलों में, क्लोन प्राप्त करना एक अच्छा विचार है, ज्यादातर मामलों में यह नहीं है। एक गेटर को कुछ भी क्लोन नहीं करना चाहिए, इसे डेटा को तब तक संशोधित नहीं करना चाहिए जब तक कि यह संभावित रूप से शून्य संग्रह या ऐसा कुछ प्रारंभ नहीं करता है। यदि आप अपरिवर्तनीय संग्रह वाले अपरिवर्तनीय संग्रह चाहते हैं, तो इसे इस तरह से करने का प्रयास करें। इस उदाहरण में हमारे पास कक्षा FooImpl
है जो बाद में समझाए जाने के कारण इंटरफ़ेस Foo
लागू करता है।
public interface Foo {
int getBar();
}
public class FooImpl Foo {
private int bar;
@Override
public int getBar() {
return bar;
}
public void setBar(int newValue) {
this.bar = newValue;
}
}
जैसा कि आप देख, फू कोई सेटर है। यदि आप कुछ ArrayList<Foo>
बनाते हैं और इसे Collections.unmodifiableList(myArrayList)
के रूप में कुछ गेटर से पास करते हैं, तो ऐसा लगता है कि आपने ऐसा किया है। लेकिन काम अभी तक नहीं किया गया है। यदि कक्षा FooImpl
सार्वजनिक है (जो इस मामले में है), तो कोई भी कोशिश कर सकता है कि वह foo
सूची में पाया गया है, वह instanceof FooImpl
है और फिर इसे (FooImpl) foo
के रूप में इसे परिवर्तनीय बनाते हैं। हालांकि, हम किसी भी Foo
को FooWrapper
नामक रैपर में लपेट सकते हैं। यह रूप में अच्छी तरह Foo
लागू करता है:
public class FooWrapper implements Foo {
private Foo foo;
public FooWrapper(Foo foo) {
this.foo = foo;
}
public int getBar() {
return foo.getBar();
}
// No setter included.
}
फिर हम एक Collection<FooWrapper>
में एक new FooWrapper(myFoo)
डाल सकते हैं। इस रैपर में कोई सार्वजनिक सेटटर नहीं है और अंदर फू निजी है। आप अंतर्निहित डेटा को संशोधित नहीं कर सकते हैं। अब उस Foo
इंटरफ़ेस के बारे में। FooImpl
और FooWrapper
दोनों इसे कार्यान्वित करते हैं, यदि कोई विधि डेटा को संशोधित करने का इरादा नहीं रखती है, तो यह इनपुट पर Foo
मांग सकता है। इससे कोई फर्क नहीं पड़ता कि आपको Foo
मिलते हैं।
इसलिए, यदि आप unmodifiable unmodifiable डेटा वाली संग्रह चाहते हैं, एक नया Collection<Foo>
बनाने FooWrapper
वस्तुओं के साथ यह फ़ीड और फिर Collections.unmodifiable*(theCollection)
कहते हैं। या कि फू के पूरे संग्रह इस सूची लपेटता, FooWrappers लौटने, उदाहरण के लिए, एक कस्टम संकलन करते हैं:
public MyUnmodifiableArrayList implements List<Foo> {
ArrayList<Foo> innerList;
public get(int index) {
Foo result = innerList.get(index);
if (!(result instanceof FooWrapper)) {
return new FooWrapper(result);
}
return result; // already wrapped
}
// ... some more List interface's methods to be implemented
}
लिपटे संग्रह के साथ, आप मूल संग्रह के माध्यम से पुनरावृति और के रैपर के साथ अपने क्लोन बनाने के लिए की जरूरत नहीं है डेटा। जब आप इसे पूरी तरह से नहीं पढ़ते हैं तो यह समाधान बहुत बेहतर होता है, लेकिन जब भी आप get()
पर कॉल करते हैं, तब तक यह एक नया FooWrapper बनाता है, जब तक कि उस अनुक्रमणिका पर फ़ू पहले से ही FooWrapper
नहीं है। लाखों कॉलों के साथ get()
पर लंबे समय तक चलने वाले धागे में, यह कचरा कलेक्टर के लिए एक अनावश्यक बेंचमार्क बन सकता है, जिससे आप कुछ आंतरिक सरणी या मानचित्र का उपयोग कर सकते हैं जिसमें पहले से मौजूद FooWrappers शामिल हैं।
अब आप नया, कस्टम List<Foo>
वापस कर सकते हैं। लेकिन फिर, एक सादा गेटर से नहीं। इसे अपने private ArrayList<FooImpl> fooList
फ़ील्ड के लिए getUnmodifiableFooList()
जैसे कुछ बनाएं।
जावा कभी वस्तुओं की प्रतिलिपि नहीं करता है। – SLaks
इस उदाहरण में एक गेटर एक वस्तु को संशोधित करता है? – raina77ow
यह सत्यापित करना आसान लगता है। पदार्थ में केवल आपके संदर्भ में संदर्भ पारित किए जाते हैं ताकि संशोधन मूल सरणी को प्रभावित कर सकें। – assylias