Java提高学习之Object(3)
終止
問:?finalize()方法是用來做什么的?
答:?finalize()方法可以被子類對象所覆蓋,然后作為一個終結者,當GC被調用的時候完成最后的清理工作(例如釋放系統資源之類)。這就是終止。默認的finalize()方法什么也不做,當被調用時直接返回。
對于任何一個對象,它的finalize()方法都不會被JVM執行兩次。如果你想讓一個對象能夠被再次調用的話(例如,分配它的引用給一個靜態變量),注意當這個對象已經被GC回收的時候,finalize()方法不會被調用第二次。
問:?有人說要避免使用finalize()方法,這是真的嗎?
答:?通常來講,你應該盡量避免使用finalize()。相對于其他JVM實現,終結器被調用的情況較少——可能是因為終結器線程的優先級別較低的原因。如果你依靠終結器來關閉文件或者其他系統資源,可能會將資源耗盡,當程序試圖打開一個新的文件或者新的系統資源的時候可能會崩潰,就因為這個緩慢的終結器。
問:?應該使用什么來替代終結器?
答:?提供一個明確的用來銷毀這個對象的方法(例如,java.io.FileInputStream的void close()方法),并且在代碼中使用try - finally結構來調用這個方法,以確保無論有沒有異常從try中拋出,都會銷毀這個對象。參考下面釋放鎖的代碼:
1 Lock l = ...; // ... is a placeholder for the actual lock-acquisition code 2 l.lock(); 3 try 4 { 5 // access the resource protected by this lock 6 } 7 finally 8 { 9 l.unlock(); 10 }這段代碼保證了無論try是正常結束還是拋出異常都會釋放鎖。
問:?什么情況下適合使用終結器?
答:?終結器可以作為一個安全保障,以防止聲明的終結方法(像是java.io.FileOutputStream對象的close()方法或者java.util.concurrent.Lock對象的Lock()方法)沒有被調用。萬一這種情況出現,終結器可以在最后被調用,釋放臨街資源。
問:?怎么寫finalize()?
答:?可以遵循下面這個模式寫finalize()方法:
1 @Override 2 protected void finalize() throws Throwable 3 { 4 try 5 { 6 // Finalize the subclass state. 7 // ... 8 } 9 finally 10 { 11 super.finalize(); 12 } 13 }? ? 子類終結器一般會通過調用父類的終結器來實現。當被調用時,先執行try模塊,然后再在對應的finally中調用super.finalize();這就保證了無論try會不會拋出異常父類都會被銷毀。
問:?如果finalize()拋出異常會怎樣?
答:?當finalize()拋出異常的時候會被忽略。而且,對象的終結將在此停止,導致對象處在一種不確定的狀態。如果另一個進程試圖使用這個對象的話,將產生不確定的結果。通常拋出異常將會導致線程終止并產生一個提示信息,但是從finalize()中拋出異常就不會。
問:?我想實踐一下finalize()方法,能提供一個范例嗎?
答:?參考代碼清單1.
1 class LargeObject 2 { 3 byte[] memory = new byte[1024*1024*4]; 4 5 @Override 6 protected void finalize() throws Exception 7 { 8 System.out.println("finalized"); 9 } 10 } 11 12 public class FinalizeDemo 13 { 14 public static void main(String[] args) 15 { 16 while (true) 17 new LargeObject(); 18 } 19 }代碼清單1:實踐finalize()
? ? 代碼清單1中的代碼寫了一個FinalizeDemo程序,重復地對largeObject類實例化。每一個Largeobject對象將產生4M的數組。在這種情況下,由于沒有指向該對象的引用,所以LargeObject對象將被GC回收。
GC會調用對象的finalize()方法來回收對象。LargeObject重載的finalize()方法被調用的時候會想標準輸出流打印一條信息。它沒有調用父類的finalize()方法,因為它的父類是Object,即父類的finalize()方法什么也不做。
編譯(javac FinalizeDemo.java)并運行(java FinalizeDemo)代碼清單1.當我在我的環境下(64位win7平臺)使用JDK7u6來編譯運行的時候,我看到一列finalized的信息。但是在JDK8的環境下時,在幾行finalized之后拋出了java.lang.OutOfMemoryError。
因為finalize()方法對于虛擬機來說不是輕量級的程序,所以不能保證你一定會在你的環境下觀察到輸出信息。
得到對象的類
問:?gerClass()方法是用來做什么的?
答:?通過gerClass()方法可以得到一個和這個類有關的java.lang.Class對象。返回的Class對象是一個被static synchronized方法封裝的代表這個類的對象;例如,static sychronized void foo(){}。這也是指向反射API。因為調用gerClass()的對象的類是在內存中的,保證了類型安全。
問:?還有其他方法得到Class對象嗎?
答:?獲取Class對象的方法有兩種。可以使用類字面常量,它的名字和類型相同,后綴位.class;例如,Account.class。另外一種就是調用Class的foeName()方法。類字面常量更加簡潔,并且編譯器強制類型安全;如果找不到指定的類編譯就不會通過。通過forname()可以動態地通過指定包名載入任意類型地引用。但是,不能保證類型安全,可能會導致Runtime異常。
轉載于:https://www.cnblogs.com/sunfie/p/5134254.html
總結
以上是生活随笔為你收集整理的Java提高学习之Object(3)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [翻译]opengl扩展教程2
- 下一篇: SQL中读取Excel 以及 bpc语言