1.關於”equals()”方法,String可以隨便用一用,JDK貌似很多類都沒有覆寫equals()方法,慎重使用。順便一說,Object的equals()方法相當於==。自己覆寫equals()方法,步驟三:<1>索引是否相等<2>是否是此類型<3>成員判斷。覆寫equals()方法,要覆寫hashcode()方法。相等的對象必須具有相等的散列碼。有些集合類都是基於散列值的,如HashMap、HashSet、Hashtable等,是根據對象的散列值將其映射到相應的散列桶。最後,當對有父類的類重寫equals()方法時,注意調用super.equals()方法。
2.在把異常向上拋出時要注意,如果在catch,finallly中執行會產生異常的語句時,有可能會覆蓋根源異常。
Java代碼
- Public class Hidden
- {
- public void foo() throws Exception
- {
- try {
- throw new Exception("First Exception"); //1
- }
- catch (Exception e) {
- throw new Exception("Second Exception"); //2
- }
- finally {
- throw new Exception("Third Exception"); //3
- }
- }
- }
3.關於throws,寫清每一個異常比寫一個他們的父類要好,因為捕獲異常的函數也許需要針對不同的異常進行操作。
比如void f() throws FileNotFoundException, EOFException, UnsupportedEncodingException
就比void f() throws IOException 要好很多。
當調用f()的函數處理異常時,碰到第二種情況就只有去看f()的源碼了。。。
這也沒神馬好總結的,JDK就是這麼做的,大抵就是這個原因吧。
4.關於繼承關於throws
Java代碼
- interface A {
- void f() throws IOException;
- }
- class B {
- @Override
- void f() …
- }
此時f()有三種選擇,<1>不拋出任何異常<2>拋出IOException<3>拋出IOException的子類異常<4>有非IOException的子類異常怎麼辦?自己內部抓住解決之。
原因是,要是不這樣,調用f()的上層方法不知道要改成神馬樣子,面向接口編程還怎麼搞。這些其實編譯器都會幫你檢查的,之所以還要說是因為注意到這個問題,了解了些許原因,感覺對異常處理突然產生些許感悟。
5.關於finally,老問題隨便寫兩句,用finally確保你的資源釋放。當有finally塊存在時,最好不要從try塊中return,否則勿必檢查finally塊不會影響程序的正常返回。下面代碼必須悲劇的。
Java代碼
- int f() {
- try {
- return 1;
- } finally {
- return 2;
- }
- }
補一點,怎麼才能不執行finally塊中語句呢?在try塊中執行到System.exit(0);語句-.-
6.關於“不要用異常控制流程”,印象中有點爭議? 關鍵在於“流程”二字,這個流程指什麼。這個流程指的是正常的程序流程,比如《Practical Java》實踐24裡面這個,但是異常的程序流程是可以處理的,比如網絡程序socket連接連著由於網絡不穩定等原因斷了,捕獲這個異常,進行重新連接或者連接服務鏡像神馬的,這個流程就是異常流程,這個不用異常控制不好處理了吧。
7.在構造函數中拋出異常,咋一看,有點怪。稍微一回憶,JDK中的Stream系列構造函數可不都是這樣的麼。Why?構造函數沒有返回值,不能從構造函數獲得傳統的錯誤報告,一旦構造函數失敗,無法從中返回錯誤碼。這麼做的好處:如果構造函數產生異常,調用段也忽略了這個異常,那麼變量的索引就會指向null,使用時就會拋出NullPointerException。如:
Java代碼
- A a = null;
- try {
- a = new A();
- } catch(XXExcption e) {…}
- // 調用a
- … …
還有一種辦法叫做二段構造法,構造函數只處理不會有異常的部分,會產生異常的部分抽離出去由另一個函數進行處理。此時就必須設置一個標志位來顯示該類是否被成功的初始化,但是這造成了在調用其它函數的時候或之前必須檢查此標志位(調用其它函數的時候是指檢查標志位的工作在每一個“其它函數”的內部最開始的部分)。
對了,以上討論的類像這種:
Java代碼
- class MyFileInputStream {
- String name;
- FileInputStream fis;
- }
初始化name時候不會錯,而初始化fis時候會有FileNotFoundException異常,不管的話會產生name有值,fis沒值是null的未完全初始化的情況,導致其它成員方法的一些錯誤。
原文鏈接:http://mylazygirl-yeah-net.Javaeye.com/blog/974477
8.拋出異常前先將對象恢復成有效狀態,嗯,理解的不夠深刻。說點別的,捕獲異常並且沒有繼續向上拋,此時程序必須能夠運行在已知的流程上,必須要正常的運行,並且不能影響下一次運行。簡單說就是捕獲異常需要處理,至少也要日志,對於處理不了的還是繼續向上拋吧。