मान लीजिए कि आप कुछ कोड एक पुस्तकालय से एक सार्वजनिक वर्ग का उपयोग करता है लिखते हैं।
import somelibrary.somepackage.SomeClass; // <-- public class from a library.
public class Main {
public static void main(String[] args) {
SomeClass.doSomething();
}
}
इसके बाद आप इस कोड संकलन है, और यह ठीक संकलित, के बाद से वर्ग का उपयोग कर रहे public
है।
अब, लाइब्रेरी के अगले संस्करण में, पैकेज को मॉड्यूल में जोड़ा गया है, लेकिन निर्यात नहीं किया गया है। इसका अर्थ यह है कि यदि आप रनटाइम मॉड्यूल पथ पर इस नए मॉड्यूल के साथ अपना कोड चलाने का प्रयास करते हैं, तो यह एक अपवाद फेंक देगा क्योंकि आप एक encapsulated पैकेज तक पहुंचने का प्रयास कर रहे हैं।
अपना कोड फिर से काम करने के लिए, आप इस मॉड्यूल को अपने कोड में खोलने के लिए कमांड लाइन विकल्प का उपयोग कर सकते हैं, ताकि यह encapsulated पैकेज का उपयोग जारी रख सके।
वैकल्पिक रूप से, लाइब्रेरी के निर्माता पुस्तकालय की मॉड्यूल परिभाषा में opens somepackage;
जोड़ सकते हैं। इससे आपको इस नए संस्करण का उपयोग करके अपने कोड को अनुमति देगा, लेकिन इसके साथ संकलित नहीं करेगा। अर्थात। public
और protected
सदस्य केवल रनटाइम पर पहुंच योग्य हैं, लेकिन इसमें कोई प्रतिबिंब शामिल नहीं है।
एक ही है जब आप एक वर्ग का विस्तार, और समझाया पैकेज में है कि एक सुपर वर्ग के एक protected
सदस्य तक पहुँचने के लिए चाहते हैं के लिए चला जाता है।
लेकिन निर्देश खोलता है तथ्य यह है कि अगर एक पुस्तकालय के अगले संस्करण में, एक विधि या क्षेत्र private
किया जाता है नहीं बदलता है, कि आप एक IllegalAccessError
मिल अगर आप इसे इस्तेमाल करने की कोशिश:
class SomeClass { // <-- the class in the library
public static void doSomething() {
System.out.println("doSomething"); // contrived example code
}
}
...
public class Main {
public static void main(String... args) throws Exception {
SomeClass.doSomething(); // this call compiles fine,
}
}
फिर, पुस्तकालय doSomething
के अगले संस्करण में private
बना है:
private static void doSomething() {...}
और पुनः संकलित। लेकिन अगर आप Main
के पुराने संस्करण को SomeClass
के नए संस्करण के साथ चलाने का प्रयास करते हैं तो आपको IllegalAccessError
मिलता है।
संक्षेप में, केवल उन सदस्यों के लिए काम करता है जो लाइब्रेरी के नए संस्करण में public
या protected
हैं। तो प्रतिबिंब के मामले में
public static void main(String... args) throws Exception {
Method m = SomeClass.class.getDeclaredMethod("doSomething");
m.setAccessible(true);
m.invoke(null); // works Fine
}
, खुलता भी फिर से समझाया होगा निजी सदस्यों सुलभ:
हालांकि, प्रतिबिंब के मामले में, आप हमेशा एक private
सदस्य पहुँच सकते हैं, setAccessible(true)
का उपयोग करके ।
मुझे नहीं पता कि मैं आपके प्रश्न को सही तरीके से समझता हूं, लेकिन इस बात पर विचार करें कि किसी के पास कोड हो सकता है जो पैकेज में सार्वजनिक एपीआई पर निर्भर करता है। फिर जावा 9 बाहर आता है और पैकेज मॉड्यूल के अंदर encapsulated है। उस विरासत कोड का उपयोग जारी रखने के लिए आपको मॉड्यूल खोलना होगा। –
मैं फिर से व्याख्या करने की कोशिश करता हूं: यदि खुला सभी प्रकार और पैकेज के सभी सदस्यों को प्रतिबिंबित करने की अनुमति देता है तो सार्वजनिक और संरक्षित केस क्यों समझाया जाता है? – xdevel2000
ठीक है धन्यवाद। ठीक है जैसे मैंने कहा, यह हो सकता है कि पैकेज एन्सेप्लेटेड होने से पहले कोई एपीआई (सामान्य तरीका, प्रतिबिंब के माध्यम से नहीं) का उपयोग कर रहा था। यह एक पिछली संगतता सुविधा प्रतीत होता है। –