分類
Java

自定義異常(customize exception)

自定義異常目的
為了表示應用程序的一些特定錯誤訊息並提供新的含意。
如考慮伺服器的連線問題雖然可以全部使用 IOException 來表示,但各種連線問題卻可再度細分,如
伺服器關閉(ServiceClosedException) , 連線超時(ConnectTimeoutException),使用者中斷(ClientInterruptException)等等。
 
Note :
自定義異常必須在Throwable 體系中派生,否則不能在應用程序中傳播。
不可直接繼承Throwable,因為Throwable已經定義好2個主要分支(Error & Exception)
也不要繼承自Error 及其子類別,因為自定義通常不符合錯誤標準。
一般繼承自Exception


 
 
自定義異常步驟
1.定義異常類別
需要繼承Throwable 或是Throwable的子類別,並提供多個建構式,最好能夠傳入String 以便儲存錯誤訊息。

public class ServiceClosedException extends Exception
{
    private Date mConnectDate = new Date();
    public ServiceClosedException() {
    }
    public ServiceClosedException(String message) {
        super(message);
    }
    public ServiceClosedException(String message, Date connectDate){
        super(message);
        mConnectDate = connectDate;
    }
    public Date getConnectDate(){
        return mConnectDate;
    }
}

 
2.聲明方法拋出自定義類別

public void connectService() throws ServiceClosedException
{
}

 
3.找到故障點,建立異常並加上關鍵字 throw

public void connectService() throws ServiceClosedException
{
        if(!mIsServiceConnect){
            throw new ServiceClosedException();
        }
}

 
4.自定義異常完成後,client呼叫會丟出自定義異常的方法就必須處理或是聲明該自定義異常

    @Test
    public void testConnectService()
    {
        try {
            connectService();
        } catch (ServiceClosedException e) {
            e.printStackTrace();
        }
    }

 
 

分類
Java

處理異常的選項(handle or declare)

1.處理(handle) : 直接捕獲異常並處理。

處理異常動作:使用異常處理區塊(try-catch-finally)

  1. try:區塊內放置可能拋出異常語句。
  2. catch:區塊內處理異常的動作,動作步驟為產生異常後,try區塊停止動作,JVM尋找相關的catch區塊。可能會有多個catch區塊,異常會交給第一個符合的catch 區塊處理。
  3. finally:無論try catch 是否會執行,finally區塊一定會執行

處理異常規則:
try之後必須接著catch 或是 finallycatchfinally可以一起出現,但必須至少有一個。
在多個catch 區塊的情況下,經驗法則為從最具體排到最一般。
選擇處理的優點:在本地端直接處理,容易找到發生問題點,方法調用者不須多寫處理。
選擇處理的缺點:缺少通用性,無法選擇其他的處理方式,因為必須多寫處理的代碼因此增加該方法的複雜度。


 
 

2.聲明(declare) : 聲明該方法拋出異常,讓呼叫端接手處理。

聲明異常動作:在方法宣告中加上 throws ExceptionName
聲明異常的規則:

  1. 必須聲明方法中可能拋出的可檢測異常(checked exception),非檢測異常(unchecked exception)不是必須的,可聲明也可以不聲明。
  2. 聲明異常類別可以是其異常子類。

選擇聲明原因:

  1. 需要傳送異常發送到系統其他部份。
  2. 無法在本地端處理異常。

 
 

3.選擇處理或是聲明異常

經驗法則:盡可能處理異常,若無法處理才聲明異常。
 


 
 

4.標準異常處理選項

1.紀錄異常相關訊息

  • 使用標準輸出或錯誤流
  • 開發自定義類
  • 使用java 紀錄api (java.util.logging)

2.要求客戶端輸入訊息
透過GUIclient 選擇下一步
3.使用預設值或替換數據

  • 簡單情況將預設值設定為靜態常量加在程式碼中。
  • 複雜情況可將預設值紀錄在配置文件(Properties)中,並在發生問題時載入。

4.將控制轉移到應用程序的其他部份

  • 簡單情況提取catch 處理方法
    try {
          result = bufferReader.readLine();
        } catch (IOException e) {
            handleReadLineException();
        }
    }
    private void handleReadLineException(){
    // do handle exception for read line
    }
  • 複雜情況開發一個異常處理類別,來集中處理應用程序代碼

5.將異常轉換成其他形式

  • 可提供更適當的上下文用來描述異常
private void connect(String ip) throws ServerConnectionException
{
        try {
            //some exception
        } catch (IOException e) {
            throw new ServerConnectionException ("specify message from Server Connect", e);
        }
}

6.準備停止系統

  • 有打開的文件就關閉
  • 有連接的資源就關閉
  • 儲存必要資訊
  • 通知其他部份應用程序即將結束

7.重試操作

  • 等待一段時間後重試操作
try {
            connect();
    } catch (IOException e) {
            retryConnect();
    }
private void retryConnect()
{
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        try{
            connect();
        }catch(IOException e){
            //retry connect
        }
    }

 
8.替換或恢復操作

  • 如無法儲存在伺服器上就改為存在本機硬碟
       try {
            saveToServer();
        } catch (IOException e) {
            saveToLocalDisk();
        }
    private void saveToLocalDisk(){
    }

 
9.忽略問題

  • 當異常對系統其他部份沒有影響,如調用 I/O stream的關閉方法
private FileReader mFileReader;
...
...
try {
      mFileReader.close();
} catch (IOException e)
{
      e.printStackTrace();
}

 


 
 

5.解決異常建議事項

  • 盡可能處理異常:盡可能處理,除非條件不予許再考慮聲明異常。
  • 具體問題具體解決:需要為特定類型的問題建立特定的處理區塊。
  • 紀錄可能影響應用程序運行的異常:可以採取永久的方式紀錄影響應用程序的異常,可以幫助處理問題
  • 根據情況將異常轉換為業務上下文:建立異常的成本不高,可以考慮為特定的問題轉換特定的異常。

 
 

6.解決異常不建議事項

  • 不要忽略異常
try {
      printStream = new PrintStream(new File("./error_record"));
      System.setOut(printStream);
      printStream.println("error message");
     } catch (FileNotFoundException e)
{//do nothing here}

 

  • 不要使用覆蓋式異常處理
    try {
          printStream = new PrintStream(new File("./error_record"));
          System.setOut(printStream);
          printStream.println("error message");
        } catch (Exception e) {
               // do something
        }
  • 不要將特定異常轉為一般異常
    try {
          printStream = new PrintStream(new File("./error_record"));
          System.setOut(printStream);
          printStream.println("error message");
        } catch (IOException e) {
                throw new Exception(exceptionMessage);
        }
  • 不要處理能夠避免的異常(使用判斷式取代拋出異常)
  • 使用
    if(printStream != null){
        printStream.println("error message");
    }
    取代
    try{
         printStream.println("error message");
    }catch(NullPointerException e){
         System.out.println(''PrintStream is null'');
    }

     

 
 
 
 
 

分類
Java

可檢測異常與非檢測異常(Checked Exception and Unchecked Exception)

可檢測異常(Check Exception)與非檢測異常(Uncheckecd Exception)

 

1.非檢測異常不需要強制處理或聲明,為 Error RuntimeException 2個類別。e.g.

public void throwUncheckedException(String target)
{
        if(target == null)
        {
            throw new NullPointerException();
        }
}

throwUncheckedException 方法為很常見的檢查方法參數有效性的動作,在方法中(第5行)會拋出NullPointerException。
 
因為 NullPointerException 為 Unchecked Exception,所以不需要在方法宣告位置(第1行)加上聲明的處理 e.g.

public void throwUncheckedException(String target) throws NullPointerException
{
        if(target == null)
        {
            throw new NullPointerException();
        }
}

Unchecked Exception 不需要強制呼叫端處理,可以直接呼叫沒問題。e.g.

@Test
public void testThrowUncheckedException()
{
        throwUncheckedException(null);
}

 
 


 

2.可檢測異常必須強制處理或聲明,主要為 Exception 及其子類別(除了RuntimeException以外)e.g.

public void throwCheckedException(String target) throws IOException
{
        if(target == null)
        {
            throw new IOException();
        }
}

throwCheckedException 在方法中(第5行)會拋出IOException,因為 IOException 屬於 Checked Exception,必須強制處理。
所以可以選擇在方法宣告聲明 IOException,讓呼叫端去處理或是在原始位置處理 e.g.

public void throwCheckedException(String target)
{
        if(target == null)
        {
            try {
                throw new IOException();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
}

 
如果選擇在方法宣告聲明IOException , 那呼叫端就必須去處理 IOException e.g.

@Test
public void testThrowCheckedException()
{
        try {
            throwCheckedException(null);
        } catch (IOException e) {
            e.printStackTrace();
        }
}

 

分類
eclipse plugins

安裝並使用 ObjectAid

ObjectAid 可以讓 code 產生對應的 uml。對於理解 Software Architecture 有相當程度的幫助。
 
1. Install ObjectAid
open eclipse(Kepler) -> Help -> install new software -> add -> type name : ObjectAid ,
type Location : http://www.objectaid.com/update ->  press next
 
2. Run ObjectAid
open eclipse(Kepler) -> select StarNetXMPPTransportBundle -> create ObjectAid UML Diagram ->
drag class from package explorer to objectAid UML Diagram
 

分類
eclipse plugins

安裝並使用 AceJump

AceJump 可以幫助在eclipse Editor 中快速移動,使用這個插件基本上不再需要滑鼠移動了。
 
1.安裝AceJump
open eclipse(Kepler) -> Help -> install new software -> add -> type name : AceJump ,
type Location : http://tobiasmelcher.github.io/acejumpeclipse/ -> press next
 
2.Run AceJump
open eclipse(Kepler) -> press “ctrl + ,” in Editor -> type which char your want to move in Editor ->
type hint char
 
3. config AceJump HotKey
Window -> Preferences -> General -> Key -> find AceJump

分類
eclipse plugins

安裝並使用 EclEmma 計算測試覆蓋率

1.Install EclEmma
open eclipse(Kepler) -> Help -> install new software -> add -> type name : EclEmma,
type Location : http://update.eclemma.org/ ->  press next
 
2.Run EclEmma
open eclipse(Kepler) -> right click project on Package Explorer -> Coverages As -> JUit Test
 
3.view unit test coverage
open eclipse(Kepler) -> open coverage view

分類
Android Uncategorized

eclipse 設定 code style

1.set customize code style

Window -> Preferences -> java -> code style -> Formatter -> import -> select your own rule xml

分類
eclipse plugins

安裝Metrics plugin on eclipse(Kepler)

1. Install Metrics:

open eclipse(Kepler) -> Help -> install new software -> add -> type name : Metrics ,
type Location : http://metrics.sourceforge.net/update -> select metrics and press next
 

2. How to use Metrics

in eclipse Package explorer -> right click project -> Properties -> Metrics -> click Enable Metrics -> Apply -> Ok
 

分類
eclipse plugins

安裝PMD plugin on eclipse(Kepler)

1. Install PMD:

open eclipse(Kepler) -> Help -> install new software -> add -> type name : PMD ,
type Location : http://sourceforge.net/projects/pmd/files/pmd-eclipse/update-site/ -> select PMD for eclipse 4 and press next

分類
Ubuntu tools

安裝並設定 autojump

1.安裝 autojump

可以先安裝 zsh  以及 oh-my-zsh 再來安裝 autojump
直接使用 apt-get 來安裝。
sudo apt-get install autojump
 

2.安裝完成後設定shell 的配置檔

zsh: 到~/.zshrc 加入以下設定

...
plugins=(git copydir copyfile autojump)
...
...
[[ -s ~/.autojump/etc/profile.d/autojump.zsh ]] && . ~/.autojump/etc/profile.d/autojump.zsh

 

3.重新啟動 zsh,輸入以下指令並重新啟動 terminal

. ~/.zshrc