अंतिमकरण संसाधनों को साफ करने के लिए उपयोग किया जाता है, जिसे कचरा कलेक्टर द्वारा मुक्त नहीं किया जा सकता है। उदाहरण के लिए, ओएस से सीधे संसाधनों को आवंटित करें (कुछ native
एपीआई के माध्यम से) संसाधन।
class Wrapper {
private long handle;
private Handle(long h) {
handle = h;
}
private static native long getHandleFromOS();
static Wrapper allocate() {
return new Handle(getHandleFromOS());
}
}
तो, क्या होता है, अपने कोड वर्ग Wrapper
का एक उदाहरण आवंटित करता है, तो: यह आमतौर पर "संभाल" (एक UNIX फ़ाइल वर्णनकर्ता या Windows हैंडल, या कुछ इसी तरह) किसी तरह का पैदावार? वैसे कक्षा किसी प्रकार के ओएस विशिष्ट संसाधन आवंटित करती है और सदस्य चर में इसका संदर्भ रखती है (हैंडल)। लेकिन क्या होता है, जब एक रैपर उदाहरण के लिए अंतिम जावा संदर्भ खो जाता है? अब, कचरा कलेक्टर (कुछ बिंदु पर) अब निष्क्रिय निष्क्रिय रैपर उदाहरण की जगह पुनः प्राप्त करेगा। लेकिन रैपर द्वारा आवंटित ओएस संसाधन का क्या होता है? यह उपरोक्त परिदृश्य में लीक हो जाएगा, जो एक बुरी चीज है, अगर यह एक महंगा संसाधन है, जैसे फाइल डिस्क्रिप्टर।
इस तरह के परिदृश्य में आपके कोड को साफ़ करने की अनुमति देने के लिए, finalize
विधि है।
class Wrapper {
private long handle;
private Handle(long h) {
handle = h;
}
protected void finalize() {
returnHandleToOS(handle);
}
private static native long getHandleFromOS();
private static native void returnHandleToOS(long handle);
static Wrapper allocate() {
return new Handle(getHandleFromOS());
}
}
अब, जब जी सी एक आवरण उदाहरण के अंतरिक्ष reclaims, finalizer सुनिश्चित करें कि संसाधन ठीक से ओएस में लौट जाता है बनाता है।
यह सब अच्छा लगता है, लेकिन जैसा कि अन्य ने पहले ही बताया है, नकारात्मकता यह है कि अंतिम रूप स्वाभाविक रूप से अविश्वसनीय है: आपको नहीं पता कि अंतिमकर्ता कब चलाया जाएगा। इससे भी बदतर: इस बात की कोई गारंटी नहीं है कि यह बिल्कुल चलाया जाएगा। तो IST सबसे अच्छा एक dispose
तंत्र प्रदान करते हैं और केवल मामले में सुरक्षा शुद्ध रूप में अंतिम रूप दिए जाने का उपयोग करने के लिए, अपने वर्ग के ग्राहकों को ठीक से उनके संदर्भ निपटान के लिए भूल जाते हैं:
class Wrapper {
private long handle;
private Handle(long h) {
handle = h;
}
protected void finalize() {
if(handle != 0) returnHandleToOS(handle);
}
public void dispose() {
returnHandleToOS(handle);
handle = 0;
}
private static native long getHandleFromOS();
private static native void returnHandleToOS(long handle);
static Wrapper allocate() {
return new Handle(getHandleFromOS());
}
}
आप यह नहीं कह सकते हैं "यदि और केवल यदि"; आप "केवल अगर" कह सकते हैं, लेकिन इस बात की कोई गारंटी नहीं है कि इसे बिल्कुल भी बुलाया जाएगा। –
@mmyers: +1। पुनः दावा -> अंतिम रूप दिया गया है, लेकिन विपरीत नहीं है। – danben
वहां कोई "लेकिन" नहीं है: यदि जीसी स्मृति को पुनः प्राप्त करने का प्रयास करता है, तो अंतिम() को कॉल किया जाता है। –