2009-07-22 11 views
17

अद्यतन: जैसा कि @PaulGroke नीचे बताता है, जावा 7 के साथ चीजें बदल गई हैं: अब AutoCloseable है। जो धाराओं से बंधे नहीं हैं और नए try-with-resources निर्माण द्वारा समर्थित हैं।क्या बंद करने योग्य को .NET के IDISposable के लिए जावा समकक्ष के रूप में उपयोग किया जाना चाहिए?

AutoCloseable .NET के IDisposable इंटरफ़ेस के लिए प्रत्यक्ष जावा समकक्ष है।


Closeable इंटरफ़ेस जावा 1.5 में पेश किया कसकर धाराओं से जुड़ा हुआ है, और यहां तक ​​कि IOException के लिए एक अपवाद विनिर्देशन होता है। इससे पता चलता है कि इसे सामान्य प्रयोजन क्लीनअप तर्क के बजाय केवल धाराओं या अन्य आईओ संबंधित गतिविधियों के लिए उपयोग किया जाना चाहिए।

निश्चित रूप से close() विधि के लिए विवरण एक धारा/आईओ संदर्भ के बाहर पूरी तरह से कोई मतलब नहीं होगा:

void close() throws IOException

इस धारा और विज्ञप्ति किसी भी प्रणाली के साथ जुड़े संसाधनों बंद करता है।

इसलिए मैं अपने खुद के इंटरफेस, Disposable घोषित करना चाहिए, उस पर एक Dispose() विधि के साथ, और प्रयोग जो .NET के IDisposable इंटरफेस के लिए एक एनालॉग के रूप में? या मुझे Closeable का फिर से उपयोग करना चाहिए, भले ही यह एकदम सही फिट न हो?

+1

@Pharap आपके द्वारा लिंक किए गए पृष्ठ पर उल्लिखित 'आईडीस्पोजेबल' को लागू करने के लिए दो अलग-अलग पैटर्न हैं। 'ऑब्जेक्ट को कार्यान्वित करना। फाइनलाइज()' केवल अपेक्षाकृत दुर्लभ परिदृश्य में आवश्यक है कि आपकी वस्तु सीधे अप्रबंधित संसाधनों को आवंटित करने के लिए ज़िम्मेदार है (यानी मूल संसाधन जो एक सुरक्षित हैंडल से लिपटे नहीं हैं)। आपका बयान है कि "आईडीआईएसपीबल 'को लागू करने के लिए .NET के अनुशंसित तरीके [...] के लिए' ऑब्जेक्ट। फ़ाइनलाइज()' 'का उपयोग करने की आवश्यकता है पूरी तरह से सही नहीं है। –

उत्तर

11

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

इंटरफेस पाठक के दिमाग में इरादे को इंगित करने के लिए प्रवृत्त होते हैं, इसलिए एक आईओ से जुड़े बंद करने योग्य इंटरफ़ेस को लागू करने वाले वर्ग को पाठक मान लेगा कि कक्षा भी आईओ-आधारित है।

जाहिर है, अगर आप बंद करना चाहते हैं तो सभी आईओ-संबंधित हैं, तो आपको क्लोजेबल का उपयोग करना चाहिए। लेकिन अन्यथा

/** Interface for objects that require cleanup post-use. Call dispose() in finally block! */ 
public interface Disposable { 
    public void dispose(); 
} 
34

के लिए जाना मुझे यकीन है कि ज्यादातर लोगों को इसके बारे में पता है, लेकिन कर रहा हूँ के बाद से इस सवाल का, जब "IDisposable जावा" (# 2 मेरे लिए परिणाम अभी) के लिए खोज शीर्ष परिणामों में अब भी है और अभी भी इसका उल्लेख नहीं किया गया है ...

जावा 7 के साथ चीजें बदल गई हैं: अब AutoCloseable है। जो धाराओं से बंधे नहीं हैं और नए try-with-resources निर्माण द्वारा समर्थित हैं।

+0

जबकि मुझे यह अजीब लगता है कि जावा ने 'आईडीस्पोजेबल' के समतुल्य होने के लिए इतना लंबा समय लगाया है, और मैंने जावा में एक महत्वपूर्ण दोष के रूप में इस तरह के निर्माण की कमी को माना है, इसलिए मैंने जावा के रचनाकारों की सराहना की ताकि दोनों को अनुमति देने की आवश्यकता को पहचान सके। कॉल स्टैक को प्रचारित करने के लिए अपवाद और क्लीनअप एक्सप्रेशन को आज़माएं। मेरी खुद की वरीयता ''प्रयास-संसाधनों' को 'क्लीनअपफेल अपवाद' में क्लीनअप ब्लॉक में होने वाले अपवादों को लपेटना होगा (जो कि 'अपवाद' ब्लॉक में क्या अपवाद - यदि कोई हो - इंगित करेगा क्लीनअप अपवादों की एक सूची के साथ) ... – supercat

+0

... और एक माध्यम भी प्रदान करता है जिसके द्वारा क्लीनअप कोड यह बता सकता है कि क्या 'try' ब्लॉक सफल हुआ या विफल रहा था (उदाहरण के लिए, यदि एक अपवाद कोड द्वारा फेंक दिया गया है जो संशोधित कर रहा है लॉक द्वारा संरक्षित कुछ, लॉक को अक्सर न तो जारी किया जाना चाहिए और न ही अनिश्चित काल तक आयोजित किया जाना चाहिए, लेकिन इसके बजाय इसे अमान्य किया जाना चाहिए ताकि ताला हासिल करने के लिए कोई लंबित या भविष्य का प्रयास तत्काल 'badLockExitException' फेंक देगा; यह प्रयास करने में मददगार होगा - स्रोत निर्माण एक लॉकिंग ऑब्जेक्ट को स्वचालित रूप से इस तरह के अर्थशास्त्र लागू करने दे सकता है)। – supercat

+1

मैं सहमत हूं, हालांकि कारण [बंद करने योग्य] (http://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html) को विस्तारित करने के लिए पिछड़े संगतता के कारण है [ऑटोक्लोसेबल] (https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html)। विचार करने की एक बात यह है कि यदि शरीर में अपवाद फेंक दिया जाता है और सफाई भी अपवाद को फेंक देती है तो बुलबुले अपवाद [getSuppressed] (http://docs.oracle.com/javase/8/docs/api/java/lang/ Throwable.html # getSuppressed--) में [close()] (https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html#close--) से अपवाद शामिल है। –

1

जब एक वर्ग यह भी संभव है घोषणा फेंकता बस छोड़ में (उस बात के लिए या AutoClosable) Closeable को लागू करने:

class X implements Closeable { 
    @Override public void close() /* I don't throw */ { 

    } 
} 

तो जब कोई एक टाइप किया वस्तु उपयोग कर रहा है वे close() को पकड़ने के लिए बिना कॉल कर सकते हैं कुछ भी:

void f() { // notice no need for throws because close() doesn't throw 
    X x = new X(); 
    try { 
     // do something 
    } finally { 
     x.close(); 
    } 
} 

यह भी उम्मीद कर कुछ भी साथ संगत है एक Closeable: इस वस्तु कहीं कि Closeable संभालती में पारित हो जाता है, तो वे इस मामले में व्यर्थ रूप से यद्यपि पहले से ही एक अपवाद की उम्मीद है और इसे सही तरीके से संभाल लें।

इस तरह Guava Closeables और जावा 7 कोशिश के साथ-संसाधनों पॉल Groke पता चलता है के रूप में लाइब्रेरी शामिल है:

try (X x = new X()) { 
    // do something 
} 

वहाँ एक दुर्लभ चेतावनी हालांकि है: आप बच्चे कक्षाओं में अपवाद एक बार reintroduce नहीं कर सकते यह छीन लिया गया है:

class Y extends X { 
            /* compile error */ 
    @Override public void close() throws IOException { 
     // Y.close clashes with X.close: overridden method does not throw IOException 
    } 
} 
संबंधित मुद्दे

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