क्या निजी तरीके वास्तव में सुरक्षित हैं?


92

जावा में privateएक्सेस संशोधक को सुरक्षित मानते हैं क्योंकि यह कक्षा के बाहर दिखाई नहीं देता है। तब बाहरी दुनिया को उस तरीके के बारे में पता नहीं होता है।

लेकिन मुझे लगा कि जावा प्रतिबिंब इस नियम को तोड़ने के लिए उपयोग कर सकता है। निम्नलिखित मामले पर विचार करें:

public class ProtectedPrivacy{

  private String getInfo(){
     return "confidential"; 
  }

}  

अब एक अन्य वर्ग से मैं जानकारी प्राप्त करने जा रहा हूँ:

public class BreakPrivacy{

   public static void main(String[] args) throws Exception {
       ProtectedPrivacy protectedPrivacy = new ProtectedPrivacy();
       Method method = protectedPrivacy.getClass().getDeclaredMethod("getInfo", null);
       method.setAccessible(true);
       Object result = method.invoke(protectedPrivacy);
       System.out.println(result.toString());
   }
} 

इस समय मैंने अभी भी निजी विधि को सुरक्षित माना है क्योंकि कुछ करने के लिए ऊपर की तरह हमें विधि का नाम पता होना चाहिए। लेकिन अगर वर्ग जिसमें किसी अन्य द्वारा लिखित निजी पद्धति है, तो हमारे पास उन की दृश्यता नहीं है।

लेकिन कोड की रेखा के नीचे से मेरी बात अमान्य हो जाती है।

Method method[] = new ProtectedPrivacy().getClass().getDeclaredMethods();

अब method[]इसमें उपरोक्त सभी चीजों को करने की आवश्यकता है। मेरा सवाल है, क्या जावा प्रतिबिंब का उपयोग करके इस तरह की चीजों से बचने का एक तरीका है?

मैं अपने प्रश्न को स्पष्ट करने के लिए जावा प्रलेखन से कुछ बिंदु उद्धृत कर रहा हूं।

एक्सेस स्तर चुनने पर युक्तियाँ:

यदि अन्य प्रोग्रामर आपकी कक्षा का उपयोग करते हैं, तो आप यह सुनिश्चित करना चाहते हैं कि दुरुपयोग से त्रुटियां नहीं हो सकती हैं। प्रवेश स्तर आपको ऐसा करने में मदद कर सकता है। सबसे अधिक प्रतिबंधात्मक पहुँच स्तर का उपयोग करें जो किसी विशेष सदस्य के लिए समझ में आता है। जब तक आपके पास कोई अच्छा कारण न हो, निजी का उपयोग करें।


1
एक पर्यवेक्षक का उपयोग करना मदद कर सकता है, क्योंकि getDeclaredMethodsकचरे की तरह दिखने वाले नामों को वापस करेगा।
dasblinkenlight

213
निजी, संरक्षित सार्वजनिक आदि सुरक्षा के लिए नहीं है, यह अच्छी तरह से लोगों को गलतियाँ करने से बचने के लिए है। सुरक्षा उपाय के रूप में इसका उपयोग न करें
रिचर्ड टिंगल

20
जावा कोड वैसे भी अपघटनीय है। एक 'हमलावर' सिर्फ एक जावा डिकम्प्रेसर डाउनलोड कर सकता है और आपके कोड को पढ़ सकता है, या 'निजी' को 'सार्वजनिक' में बदल सकता है।
11684

7
@RichardTingle ने क्या टिप्पणी की (+1 btw) विस्तृत करने के लिए। सुरक्षा और सुरक्षा के बीच एक महान और महत्वपूर्ण अंतर है। जहां बाद में पहुंच संशोधक के साथ समस्या को कम किया गया है; दुर्घटना से
उपयोगकर्ता

3
यह सब उन प्रोग्रामर्स के लिए बहुत स्पष्ट है जहां पहुंच संशोधक मौजूद नहीं हैं, जैसे कि पायथन में। इन भाषाओं में निजी / सार्वजनिक नामों में एक सम्मेलन द्वारा प्रतिष्ठित किया जाता है (अजगर में कुछ भी जो एकल अंडरस्कोर से शुरू होता है, उसे निजी माना जाना चाहिए)। इससे यह स्पष्ट हो जाता है कि किसी चीज़ को "निजी" के रूप में चिह्नित करना किसी भी सुरक्षा को नहीं जोड़ता है, लेकिन यह केवल कहने का एक सरल तरीका है कि लोगों को आपके एपीआई का उपयोग क्या करना चाहिए । मुझे इस बात पर संदेह है कि इस चीज़ के लिए एक कंपाइलर की जाँच में मदद मिलती है क्योंकि "बाहरी" मदद के बिना अधिवेशन का पालन करना आसान है।
बाकुरू

जवाबों:


95

यह निर्भर करता है कि आप "सुरक्षित" से क्या मतलब है। यदि आप एक सुरक्षा प्रबंधक के साथ चल रहे हैं जो इस प्रकार की अनुमति देता है, तो हाँ, आप प्रतिबिंब के साथ सभी प्रकार की गंदी चीजें कर सकते हैं। लेकिन फिर उस तरह के माहौल में लाइब्रेरी को शायद वैसे भी सार्वजनिक करने के लिए संशोधित किया जा सकता है।

इस तरह के वातावरण में एक्सेस कंट्रोल प्रभावी रूप से "सलाहकार" है - आप प्रभावी रूप से अच्छी तरह से खेलने के लिए कोड पर भरोसा कर रहे हैं। यदि आप अपने द्वारा चलाए जा रहे कोड पर भरोसा नहीं करते हैं, तो आपको अधिक प्रतिबंधक सुरक्षा प्रबंधक का उपयोग करना चाहिए।


3
स्पर्शरेखा, मुझे पता है, लेकिन क्या आप इस बारे में थोड़ा विस्तार से बता सकते हैं कि एक अधिक प्रतिबंधक प्रबंधक इस अर्थ में क्या होगा?
ग्रे

12
@Gray: सुरक्षा प्रबंधक का एक उदाहरण जो check*मूल रूप से संबंधित कॉल पर अपवाद फेंकता है ।
जॉन स्कीट

40

एक्सेस मॉडिफायर का सुरक्षा से कोई लेना-देना नहीं है। वास्तव में आप सुरक्षा के रिवर्स के रूप में एक्सेस संशोधक को देख सकते हैं - यह आपके डेटा या एल्गोरिदम को बचाने के लिए नहीं है, यह लोगों को आपके डेटा और एल्गोरिदम के बारे में जानने की आवश्यकता से बचाने के लिए है। यही कारण है कि डिफ़ॉल्ट संशोधक पैकेज है - यदि वे उस पैकेज पर काम कर रहे हैं जो उन्हें पहले से ही जानना आवश्यक है।

डेटा और आपके कोड के तरीकों के ज्ञान के साथ-साथ, यह जानने के लिए प्रतिक्रियाशीलता आती है कि इसका उपयोग कब और कैसे करना है। आप किसी को इसके बारे में पता लगाने से रोकने के लिए अपने inIt मेथड पर प्राइवेट नहीं करते हैं, आप ऐसा इसलिए करते हैं क्योंकि (क) उन्हें पता नहीं चल रहा है कि आप केवल फू के बाद कॉल करते हैं और केवल बार = 3.1415 और (बी) क्योंकि यह उन्हें इसके बारे में जानने के लिए अच्छा नहीं करता है।

एक्सेस मॉडिफ़र्स को एक सरल वाक्यांश "टीएमआई, यार, में अभिव्यक्त किया जा सकता है, इसलिए मुझे यह जानने की आवश्यकता नहीं थी"।


3
शानदार उत्तर, लेकिन मुझे यह पता लगाने के लिए Google की आवश्यकता थी कि TMI का अर्थ बहुत अधिक जानकारी है। मुझे लगता है कि मुझे घाटी में अधिक समय बिताने की आवश्यकता है :-)
मिकेलॉन्ग

7

'सुरक्षित' कहकर, आप अपनी या अन्य डेवलपर्स की रक्षा कर रहे हैं, जो आपके निजी पद्धति को कॉल करके ऑब्जेक्ट को नुकसान नहीं पहुंचाने के लिए आपके एपीआई का उपयोग कर रहे हैं। लेकिन अगर आपको या उन्हें वास्तव में इस पद्धति को कॉल करने की आवश्यकता है, तो वे इसे प्रतिबिंब के साथ कर सकते हैं।


6

सवाल यह है कि आप इसे किससे बचाने की कोशिश कर रहे हैं । मेरी राय में, आपके कोड का ऐसा ग्राहक यहां नुकसान में है।

कोड का कोई भी टुकड़ा (जो आपके या अन्य द्वारा लिखा गया है) जो privateउपरोक्त वर्ग के सदस्य तक पहुंचने की कोशिश करता है, अनिवार्य रूप से अपनी कब्र खोद रहा है। privateसदस्य सार्वजनिक API का हिस्सा नहीं बनाते हैं और बिना सूचना के परिवर्तन के अधीन हैं। यदि कोई ग्राहक ऊपर दिए गए तरीके से ऐसे निजी सदस्यों में से किसी एक का उपभोग करने के लिए होता है, तो यह टूटने वाला है यदि यह एपीआई के एक नए संस्करण में अपग्रेड करता है जिसमें निजी सदस्य को संशोधित किया गया है।


5

सुविधा के साथ, जिम्मेदारी आती है। ऐसी चीजें हैं जो आप नहीं कर सकते हैं, और वे चीजें जो आप कर सकते हैं लेकिन आपको ऐसा नहीं करना चाहिए

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


5

यदि आप अपने एपीआई के क्लाइंट प्रोग्रामर पर भरोसा करते हैं, तो यह देखने का एक और तरीका है कि उन विशेष कार्यों का उपयोग करना उनके लिए कितना 'सुरक्षित' है।

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

यदि कोई क्लाइंट प्रोग्रामर इन एब्स्ट्रैक्ट को दरकिनार करने के लिए अपने रास्ते से बाहर जाता है, तो वे एक तरह से घोषणा करते हैं कि वे जानते हैं कि वे क्या कर रहे हैं। इससे भी महत्वपूर्ण बात, वे समझते हैं कि यह असमर्थित है और आपके कोड के भविष्य के संस्करणों के साथ काम करना बंद कर सकता है।


5

privateसुरक्षा के लिए नहीं है, यह कोड को साफ रखने और गलतियों को रोकने के लिए है। यह उपयोगकर्ताओं को अन्य मॉड्यूल के सभी विवरणों के बारे में चिंता किए बिना कोड (और इसे कैसे विकसित किया जाता है) को संशोधित करने की अनुमति देता है

एक बार जब आप अपना कोड जारी करते हैं, तो लोग यह पता लगा सकते हैं कि यह कैसे काम करता है। यदि आप अंततः कंप्यूटर पर कोड चलाना चाहते हैं तो तर्क को "छिपाने" का कोई तरीका नहीं है। यहां तक ​​कि बाइनरी को संकलित करना एक झगड़े का स्तर है।

इसलिए, ऐसा कोई तरीका नहीं है कि आप अपने एपीआई को उन विशेष कामों के लिए सेट कर सकें जिन्हें आप नहीं चाहते हैं कि अन्य लोग कॉल करने में सक्षम हों। एक वेब एपीआई के मामले में, आप उन तरीकों को डाल सकते हैं जो आप सर्वर पर नियंत्रण चाहते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.