2009-07-01 11 views
135

मुझे C# के ref कीवर्ड के समान अर्थशास्त्र पसंद है।क्या मैं जावा में संदर्भ द्वारा पैरामीटर पास कर सकता हूं?

+0

सलाम। यह उत्तर मेरी समस्या का समाधान करता है: [http://stackoverflow.com/a/9324155/1676736 ](httpoverflow.com/a/9324155/1676736) –

उत्तर

210

जावा भ्रमित है क्योंकि सबकुछ द्वारा पारित किया जाता है। हालांकि संदर्भ प्रकार संदर्भ प्रकार (यानी आदिम प्रकार का पैरामीटर नहीं) यह संदर्भ है जो मान द्वारा पारित किया जाता है, इसलिए दिखाई देता है (और लोग अक्सर दावा करते हैं कि यह है)।

Object o = "Hello"; 
mutate(o) 
System.out.println(o); 

private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o! 

कंसोल के लिए Hello प्रिंट होगा: इस मामले में, के रूप में पालन करके नहीं दिखाया है। मुझे नहीं लगता कि आप कर सकते हैं

AtomicReference<Object> ref = new AtomicReference<Object>("Hello"); 
mutate(ref); 
System.out.println(ref.get()); //Goodbye! 

private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); } 
+46

इसके अलावा, लंबाई 1 की एक सरणी का उपयोग किया जा सकता है यदि आप वास्तव में लोगों को भ्रमित करना चाहते हैं तो एक संदर्भ बनाएं :) – Christoffer

+1

यह बहुत सच है –

+2

परमाणु संदर्भ और इसी वर्ग (परमाणु इंटेगर) ऐसे परिचालनों के लिए सबसे अच्छे हैं – Naveen

10

: विकल्प यदि आप Goodbye मुद्रित करने के लिए ऊपर दिए गए कोड चाहता था उपयोग एक स्पष्ट संदर्भ इस प्रकार कर रहे हैं। आपका सबसे अच्छा विकल्प उस चीज को समाहित करना है जिसे आप "रेफरी द्वारा" किसी दूसरे वर्ग के उदाहरण पर पास करना चाहते हैं, और (बाहरी) वर्ग के संदर्भ (मान द्वारा) पास कर सकते हैं। यदि आप देखते हैं कि मेरा क्या मतलब है ...

यानी आपकी विधि उस ऑब्जेक्ट की आंतरिक स्थिति को बदलती है जो इसे पारित किया जाता है, जो तब कॉलर को दिखाई देता है।

23

जावा में भाषा स्तर पर कुछ भी नहीं है रेफ। जावा में केवल मूल्य अर्थ

से गुजर रहा है जिज्ञासा की खातिर आप लागू कर सकते हैं एक रेफरी की तरह जावा बस एक परिवर्तनशील कक्षा में अपने वस्तुओं लपेटकर में अर्थ:

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(); 
    } 
} 

testcase:

public void changeRef(Ref<String> ref) { 
    ref.set("bbb"); 
} 

// ... 
Ref<String> ref = new Ref<String>("aaa"); 
changeRef(ref); 
System.out.println(ref); // prints "bbb" 
+1

क्या दूसरी पंक्ति को अंतिम पंक्ति "टेस्ट (रेफरी) पढ़ा जाना चाहिए;"? –

+0

@ ब्रायन फिशर: निश्चित, धन्यवाद – dfa

+0

इसके बजाय java.lang.ref.Reference का उपयोग क्यों नहीं करें? – Hardcoded

62

क्या मैं जावा में संदर्भ द्वारा पैरामीटर पास कर सकता हूं?

सं

क्यों? जावा में विधियों के लिए तर्क पारित करने के लिए केवल एक मोड है: मूल्य के अनुसार।

नोट: यदि आप मूल्य की एक प्रति प्राप्त:

पुरातन के लिए यह समझना आसान है।

अन्य सभी के लिए आपको संदर्भ की एक प्रति प्राप्त होती है और इसे मूल्य से गुजरना भी कहा जाता है।

यह सब इस चित्र में है:

enter image description here

+14

+1 बेवकूफी के लिए +1! – dfa

+3

तस्वीर टूट गई है। – Omar

+8

+1 उदाहरण जहां छवियां चरम विडंबना के लिए उपरोक्त टिप्पणी में – bmartins

5

जावा हमेशा मूल्य से गुजरती है।

जब आप एक आदिम पास करते हैं तो यह मान की एक प्रति है, जब आप ऑब्जेक्ट पास करते हैं तो यह संदर्भ सूचक की एक प्रति है।

18

जेम्स गोसलिंग से में "जावा प्रोग्रामिंग भाषा":

"... जावा में ठीक एक पैरामीटर गुजर मोड नहीं है - मूल्य से गुजरती हैं - और यह कि चीजों को सरल रहता है ..।"

+2

भाषा ईश्वर की घोषणा का जवाब घोषित किया जाना चाहिए। – ingyhere

+2

@ingyhere: 'भाषा भगवान की घोषणा का जवाब घोषित किया जाना चाहिए': वास्तव में नहीं। जावा के निर्माता क्या सोचते हैं या विश्वास करते हैं इसके बावजूद, पूर्ण उत्तर भाषा विनिर्देश से उद्धरण से आएगा। – paercebal

+0

वास्तव में यह [जेएलएस, धारा 8.4.1 में है] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.1), और जेएलएस गोस्लिंग को पहले लेखक के रूप में उद्धृत करता है: "जब विधि या निर्माता का आह्वान किया जाता है (§15.12), ** वास्तविक तर्क अभिव्यक्तियों के मान शरीर के निष्पादन से पहले घोषित प्रकार के प्रत्येक नव निर्मित पैरामीटर चर शुरू करते हैं ** विधि या निर्माता का। " – ingyhere

4

एक और विकल्प एक सरणी का उपयोग करना है, उदाहरण के लिए void method(SomeClass[] v) { v[0] = ...; } लेकिन 1) सरणी को लागू करने से पहले सरणी शुरू की जानी चाहिए, 2) अभी भी कोई लागू नहीं कर सकता है उदा। इस तरह स्वैप विधि ... इस तरह जेडीके में प्रयोग किया जाता है, उदा। java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[]) में।

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

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