2011-02-26 11 views
11

मैं इस धारणा के तहत था कि निजी गैर स्थैतिक चर केवल उस ऑब्जेक्ट पर कॉल किए गए तरीकों से पहुंचा जा सकता है, जिसमें वेरिएबल्स रहते हैं, लेकिन ऐसा नहीं है। क्या कोई निम्नलिखित तर्कों को समझा सकता है कि निम्नलिखित क्यों संकलित और चलाते हैं?निजी वैरिएबल तक पहुंचने वाली जावा स्थैतिक विधियां

public class Sandbox { 
    private String _privateString = "unmodified"; 
    public static void setPrivateString(String str, Sandbox s) { 
     s._privateString = str; 
    } 
    public String toString() 
    { 
     return _privateString; 
    } 

    public static void main(String[] args) { 
     Sandbox s = new Sandbox(); 
     setPrivateString("modified", s); 
     System.out.println(s); 
    } 
} 

आउटपुट:

modified 

संपादित करें: एक ही सी # में सच है।

+0

आप '_privateString' को सीधे 'मुख्य()' से उसी वर्ग में संशोधित कर सकते थे। –

उत्तर

17

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

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

+1

तो किसी वर्ग के किसी भी उदाहरण के उस वर्ग के अन्य सभी उदाहरणों के सभी निजी चरों तक पहुंच है? –

+0

बिल्कुल! जो पहले अजीब लग सकता है, हालांकि एक वर्ग के संदर्भ में जब आप एक ही कार्यान्वयन के बारे में सोचते हैं तो यह समझ में आता है। – davin

+0

@ टीके।तो उदाहरण के लिए, 'सार्वजनिक शून्य परिवर्तन अन्य (स्ट्रिंग परिवर्तन करने के लिए, सैंडबॉक्स एस) {s._privateString = change; } 'को किसी अन्य उदाहरण पर निष्पादित किया जा सकता है: 's1.changeOther (" blah ", s2);' – davin

2

नियम सरल है। एक वर्ग के सदस्य विधियां एक ही कक्षा के निजी सदस्यों को उनके दृश्यता संशोधक के बावजूद स्वीकार कर सकती हैं और संशोधित कर सकती हैं।

3

जैसा कि कुछ अन्य पदों में बताया गया है, जावा की दृश्यता प्रणाली कक्षा-आधारित है, न कि ऑब्जेक्ट-आधारित एक।

ध्यान दें कि इसका उपयोग कंपाइलर में किया जाता है: जब आपके पास कक्षाएं घोंसला होती हैं और आप बाहरी वर्ग के निजी क्षेत्र तक पहुंचते हैं, तो पहुंच की अनुमति देने के लिए सार्वजनिक सिंथेटिक स्थैतिक विधि उत्पन्न होती है। इसे आम तौर पर "$ 0 का उपयोग" नाम दिया जाता है। आप एक बाइटकोड बना सकते हैं जो इन कृत्रिम तरीकों का उपयोग करके प्रतिबिंब एपीआई के बिना encaplulation का उल्लंघन करता है। आप उन्हें निजी सदस्यों तक पहुंच सक्षम किए बिना प्रतिबिंब API से भी एक्सेस कर सकते हैं। कई पागल चीजें हो सकती हैं ...

यदि ऐसी दृश्यता प्रणाली नहीं थी, तो संकलक शायद इसे किसी अन्य तरह संकलित करने की आवश्यकता होगी।

... होवेवर, अंत प्रोग्रामर आमतौर पर इस विवरण को जानने की आवश्यकता नहीं है। आईडीई में कोड पूर्ण होने में कृत्रिम तरीकों को शामिल नहीं किया गया है और मुझे आशा है कि संकलक (जैस्मीन को छोड़कर) आपको इसका उपयोग करने की अनुमति नहीं देते हैं। इसलिए यदि आप बाइटकोड उत्पन्न नहीं करते हैं और प्रतिबिंब API का उपयोग नहीं करते हैं और आप इन विधियों को स्टैकट्रैक में अनदेखा करते हैं, तो आपको शायद इस विवरण को जानने की आवश्यकता नहीं है।

3

के साथ आप visibility को भ्रमित कर रहे हैं। आवृत्ति चर एक उदाहरण के दायरे में हैं, इसलिए उन्हें सीधे एक स्थिर विधि में उपयोग नहीं किया जा सकता है, लेकिन केवल एक उदाहरण संदर्भ योग्यता के साथ: s._privateString आपके मामले में।

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