जवाबों:
जावा भ्रमित कर रहा है क्योंकि सब कुछ मूल्य द्वारा पारित किया गया है । हालाँकि संदर्भ प्रकार के एक पैरामीटर के लिए (अर्थात आदिम प्रकार का पैरामीटर नहीं) यह संदर्भ ही है जिसे मूल्य द्वारा पारित किया जाता है, इसलिए यह पास-बाय-संदर्भ प्रतीत होता है (और लोग अक्सर दावा करते हैं कि यह है)। यह मामला नहीं है, जैसा कि निम्नलिखित द्वारा दिखाया गया है:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Hello
कंसोल पर प्रिंट होगा । यदि आप उपरोक्त कोड को प्रिंट करना चाहते हैं तो एक स्पष्ट संदर्भGoodbye
का उपयोग इस प्रकार है:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
क्या मैं जावा में संदर्भ द्वारा पैरामीटर पारित कर सकता हूं?
नहीं।
क्यों ? जावा में विधियों के लिए तर्क देने का केवल एक ही तरीका है: मूल्य से।
ध्यान दें:
प्राथमिकताओं के लिए यह समझना आसान है: आपको मूल्य की एक प्रति मिलती है।
अन्य सभी के लिए आपको संदर्भ की एक प्रति मिलती है और इसे मूल्य से गुजरना भी कहा जाता है।
यह इस चित्र में है:
जावा में रेफ के समान भाषा स्तर पर कुछ भी नहीं है । जावा में केवल मूल्य शब्दार्थ से गुजर रहा है
जिज्ञासा के लिए आप जावा में रेफ-जैसे शब्दार्थ को लागू कर सकते हैं बस अपनी वस्तुओं को एक उत्परिवर्ती कक्षा में लपेट सकते हैं:
public class Ref<T> {
private T value;
public Ref(T value) {
this.value = value;
}
public T get() {
return value;
}
public void set(T anotherValue) {
value = anotherValue;
}
@Override
public String toString() {
return value.toString();
}
@Override
public boolean equals(Object obj) {
return value.equals(obj);
}
@Override
public int hashCode() {
return value.hashCode();
}
}
परीक्षण का मामला:
public void changeRef(Ref<String> ref) {
ref.set("bbb");
}
// ...
Ref<String> ref = new Ref<String>("aaa");
changeRef(ref);
System.out.println(ref); // prints "bbb"
AtomicReference
(गैर-आदिम के लिए) का उपयोग करें? या AtomicSomething
(जैसे AtomicBoolean
:) आदिम के लिए?
int
के बजाय Integer
, bool
के बजाय Boolean
और इतने पर? यानी, रैपर क्लास (जो सिंटैक्स के बारे में चिंता करने पर स्वचालित रूप से अपरिवर्तित होती हैं) काम नहीं करती हैं?
जेम्स गोसलिंग से "द जावा प्रोग्रामिंग लैंग्वेज" में:
"... जावा में बिल्कुल एक पैरामीटर पासिंग मोड है - मान से पास - और वह चीजों को सरल रखता है। .."
The pronouncement of the language god should be declared the answer
वास्तव में नहीं। जावा के निर्माता क्या सोचते हैं या विश्वास करते हैं, इसके बावजूद, निरपेक्ष उत्तर भाषा विनिर्देश के एक उद्धरण से आएगा।
मुझे नहीं लगता कि आप कर सकते हैं। आपका सबसे अच्छा विकल्प उस चीज़ को एनकैप्सुलेट करना हो सकता है जिसे आप किसी अन्य श्रेणी के उदाहरण पर "रेफरी" से पास करना चाहते हैं, और (बाहरी) वर्ग के संदर्भ (मूल्य के अनुसार) को पास करें। मेरा क्या मतलब है अगर आप वह समझ सकें...
यानी आपका तरीका उस ऑब्जेक्ट की आंतरिक स्थिति को बदल देता है जो इसे पारित किया जाता है, जो तब कॉलर को दिखाई देता है।
एक अन्य विकल्प एक सरणी का उपयोग करना है, उदाहरण के लिए,
void method(SomeClass[] v) { v[0] = ...; }
लेकिन 1) विधि को लागू करने से पहले सरणी को आरंभीकृत किया जाना चाहिए, 2) अभी भी कोई इस तरह से स्वैप विधि को लागू नहीं कर सकता है ... इस तरह से JDK में उपयोग किया जाता है, जैसे java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[])
।