2011-08-12 9 views
5

मेरे पास एक अंतिम श्रेणी() विधि के साथ दूरबीन कन्स्ट्रक्टर के साथ एक सुपर क्लास है। Subclasses के खिलाफ सुरक्षा के लिए सुपर। Finalize करने के लिए भूलने के लिए, मैंने एक फाइनलाइज़र अभिभावक (ईजे आइटम 7) लिखा है।जावा फाइनलाइज़र अभिभावक काम नहीं कर रहा है?

public class Super { 

    public Super() {} 

    { 
     Object finalizerGuardian = new Object() { 
      @Override 
      protected void finalize() { 
       System.out.println("Finalizer guardian finalize"); 
       Super.this.finalize(); 
      } 
     }; 
    } 

    protected void finalize() { 
     System.out.println("Super finalize"); 
    } 

} 

यहां नमूने के उपवर्ग है -

public class Sub extends Super { 

    public Sub() {} 

    protected void finalize() { 
     System.out.println("Sub finalize"); 
    } 

    public static void main(String[] args) 
      throws InterruptedException { 
     if (1 == 1) { 
      Sub s1 = new Sub(); 
     } 
     Runtime.getRuntime().gc(); 
     Thread.sleep(10000); 
    } 
} 

एस 1 वस्तु क्षेत्र से बाहर हो जाता है, finalizer अभिभावक की अंतिम रूप देने() कहा जाता हो जाता है, और मैं उपवर्ग के अंतिम रूप देने विधि से SYSO मिलता है, लेकिन सुपर को अंतिम रूप देने से कभी नहीं मिलता।

मैं उलझन में हूं। क्या मैं मूल रूप से कुछ गलत समझ रहा हूं?

अस्वीकरण: मुझे एहसास है कि अंतिमकर्ता खतरनाक हैं और सलाह नहीं देते हैं, आदि। फिर भी समस्या को समझने की कोशिश कर रहे हैं।

उत्तर

8

प्रभावी जावा के finalizer अभिभावक (उदाहरण के लिए, Super है कि वास्तविक को अंतिम रूप देने प्रदर्शन करने के कुछ तरीके कहते हैं) आवश्यक अंतिम रूप देने के तर्क ही प्रदर्शन करना चाहिए बजाय finalize() विधि कहते हैं, क्योंकि आपके मामले में Super.this.finalize(); वास्तव में उपवर्ग से ओवरराइड प्रणाली को बुलाती है ।

भी ध्यान रखें कि finalizer अभिभावक वर्ग के एक क्षेत्र होना चाहिए:

public class Super { 
    private final Object finalizerGuardian = new Object() { 
      @Override 
      protected void finalize() { 
       Super.this.doFinalize(); 
      } 
    }; 

    private void doFinalize() { 
     System.out.println("Super finalize"); 
    } 
} 
+0

स्पष्ट समस्या को देखने के लिए "यह काम नहीं करता" में पकड़ा गया। धन्यवाद!! – Kal

2

आप Sub में Super.finalize() विधि ओवरलोडिंग कर रहे हैं। यही कारण है कि इसे बुलाया नहीं जा रहा है।

तो जब आप "Super.this.finalize(); पर कॉल करते हैं तो आप वास्तव में Sub.finalize() पर कॉल कर रहे हैं।

2

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

यदि आप अपनी पहली समस्या को ठीक करते हैं (अंतिम श्रेणी को अंतिम रूप देने वाले आपकी कक्षा में अंतिम विधि को परिभाषित करके), तो आपको अभी भी फाइनलज़रगार्डियन को आवृत्ति चर में सहेजने की आवश्यकता होगी।

2

Super.finalize() कॉल नहीं किया जा रहा है क्योंकि सब इसे ओवरराइड करता है। Super._finalize() विधि जोड़ने और इसे Super.finalize() और अंतिमकर्ता अभिभावक से कॉल करने का प्रयास करें।

इसके अलावा, मुझे लगता है कि finalizerGuardian को Super का क्षेत्र होना चाहिए। अन्यथा, अगर सुपर ऑब्जेक्ट अभी भी दृढ़ता से पहुंच योग्य है तो भी यह कचरा इकट्ठा कर सकता है।

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