2012-05-10 9 views
16

यदि कोई ऑब्जेक्ट संदर्भ किसी विधि को पास किया गया है, तो क्या ऑब्जेक्ट को विधि को "केवल पढ़ने" बनाना संभव है?क्या किसी ऑब्जेक्ट को "केवल पढ़ने के लिए" एक विधि बनाना संभव है

+5

एक पुराना है, लेकिन अभी भी अच्छा संसाधन है: http://www.cs.uwm.edu/~boyland/papers/readonly-talk.pdf –

+0

ऑब्जेक्ट के संदर्भ को संग्रहीत करने के बारे में क्या है, इसे क्लोन करें और समय-समय पर तुलना करें अगर कुछ भी नहीं बदला? –

उत्तर

15

कड़ाई से बोल नहीं रहा। यही वह संदर्भ है जो किसी ऑब्जेक्ट को म्यूटेट कर सकता है उसे किसी संदर्भ में परिवर्तित नहीं किया जा सकता है जो किसी ऑब्जेक्ट को म्यूटेट नहीं कर सकता है। साथ ही, व्यक्त करने का कोई तरीका नहीं है कि एक प्रकार अपरिवर्तनीय या परिवर्तनीय है, सम्मेलनों का उपयोग करने के अलावा।

एकमात्र विशेषता है जो अपरिवर्तनीयता के कुछ रूप सुनिश्चित करेगी final फ़ील्ड - एक बार लिखा गया है कि उन्हें संशोधित नहीं किया जा सकता है।

कहा जाता है कि कक्षाओं को डिजाइन करने के तरीके हैं ताकि अवांछित उत्परिवर्तन को रोका जा सके। यहाँ कुछ तकनीकें हैं:

  • Defensive Copying। ऑब्जेक्ट की प्रतिलिपि पास करें, ताकि अगर इसे उत्परिवर्तित किया जाए तो यह आपके आंतरिक इनवेंचर्स को तोड़ नहीं देता है।

  • उपयोग पहुँच संशोधक और/या इंटरफ़ेस केवल केवल पढ़ने के तरीकों का पर्दाफाश करने के। आप एक्सेस मॉडिफायर (public/private/protected) का उपयोग कर सकते हैं, संभवतः इंटरफ़ेस के साथ संयुक्त हो सकते हैं, ताकि अन्य ऑब्जेक्ट्स के लिए केवल कुछ विधियां दिखाई दे सकें। यदि प्रकट किए गए तरीकों को केवल प्रकृति द्वारा पढ़ा जाता है, तो आप सुरक्षित हैं।

  • अपनी ऑब्जेक्ट डिफ़ॉल्ट द्वारा अपरिवर्तनीय बनाएं। ऑब्जेक्ट पर कोई भी ऑपरेशन वास्तव में ऑब्जेक्ट की प्रतिलिपि देता है।

यह भी ध्यान दें कि एसडीके में एपीआई में कभी-कभी विधियां होती हैं जो किसी ऑब्जेक्ट का अपरिवर्तनीय संस्करण लौटाती हैं, उदा। Collections.unmodifiableList। एक अपरिवर्तनीय सूची को बदलने का प्रयास अपवाद फेंक देगा। यह स्थैतिक रूप से अपरिवर्तनीयता लागू नहीं करता है (स्थैतिक प्रकार प्रणाली के साथ संकलन-समय पर), लेकिन यह गतिशील रूप से (रन-टाइम पर) लागू करने का एक सस्ता और प्रभावी तरीका है।

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

परीक्षक फ्रेमवर्क बहुत दिलचस्प है। परीक्षक फ्रेमवर्क में, जेनेरिक यूनिवर्स प्रकार चेकर, आईजीजे अपरिवर्तनीयता परीक्षक, और जावरी अपरिवर्तनीयता परीक्षक देखें। ढांचा एनोटेशन का उपयोग करके काम करता है, इसलिए यह घुसपैठ नहीं कर रहा है।

+0

केवल पढ़ने के लिए पीडीएफ लिंक सड़ांध से पीड़ित है। – flup

3

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

6

नहीं, सजाने, संयोजन, क्लोनिंग, आदि

6

बिना वहाँ उस के लिए कोई सामान्य तंत्र है। इसे प्राप्त करने के लिए आपको विशेष-केस कोड लिखना होगा, जैसे एक अपरिवर्तनीय रैपर लिखना (Collections.unmodifiableList देखें)।

1

आप वस्तुओं के सभी मानकों को final के रूप में परिभाषित कर सकते हैं लेकिन यह ऑब्जेक्ट को केवल सभी को पढ़ता है।

3

आप इस जैसे विधि, का पहला विवरण Object क्लोनिंग द्वारा ज्यादातर मामलों में एक समान बात को प्राप्त कर सकता है ...

public void readOnlyMethod(Object test){ 
    test = test.clone(); 
    // other code here 
} 

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

+1

इस ऑब्जेक्ट को वास्तव में 'क्लोन' को सही ढंग से कार्यान्वित करने की आवश्यकता है और चूंकि यह एक एफ * एड-अप एपीआई है, इसलिए आधुनिक कक्षाएं शायद ही कभी परेशान होती हैं। –

+0

सही। हालांकि, मुझे उम्मीद है कि अधिकांश कोर जावा कक्षाओं को 'क्लोन()' को ठीक से कार्यान्वित करना चाहिए, इसलिए इसमें * अधिकांश * स्थितियां शामिल होंगी। संभवतः करीब के रूप में आप केवल पढ़ने के लिए पैरामीटर – wattostudios

+1

के लिए प्राप्त करने जा रहे हैं 'संग्रह .unmodifiableList' - जो मूल एपीआई (कोई क्लोनिंग) से है। –

0

इस पर निर्भर करता है कि आप नियम कहां लागू करना चाहते हैं। यदि आप किसी प्रोजेक्ट पर सहयोगी रूप से काम कर रहे हैं, तो final का उपयोग करें, जिसमें अगली व्यक्ति को यह बताया गया है कि वे इस मान को संशोधित करने के लिए नहीं हैं। अन्यथा आप पर ऑब्जेक्ट को स्पर्श नहीं करेंगे?

public static void main(String[] args) { 
    cantTouchThis("Cant touch this"); 
} 

/** 
* 
* @param value - break it down 
*/ 
public static void cantTouchThis(final String value) { 
    System.out.println("Value: " + value); 
    value = "Nah nah nah nah"; //Compile time error 
} 

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

0
private boolean isExecuteWriteQueue = false; 
public boolean isWriting(){ 
    final boolean b = isExecuteWriteQueue; 
    return b; 
} 
1

यह एक इंटरफ़ेस जो केवल केवल तरीकों (कोई सेटर विधि) पढ़ा है यह एक वस्तु की एक प्रति देता है (सड़क केवल कॉपी) को लागू कर रहे हैं और इंटरफ़ेस का केवल पढ़ने के लिए उदाहरण के लौटने के बजाय का उदाहरण लौटने एक ऑब्जेक्ट खुद

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

  • कोई संबंधित समस्या नहीं^_^