鍍金池/ 問答/Java  數(shù)據(jù)庫/ 重構:Java特別的接口修改:在throws子句中添加一個異常?

重構:Java特別的接口修改:在throws子句中添加一個異常?

《重構:改善既有代碼的設計》
P65:Java之中還有一個特別關于「修改接口」的問題:在Throws子句中增加一個異常。這并不是對簽名式(signature)的修改,所以你無法以delegation(委托手法)隱 藏它。但如果用戶代碼不做出相應修改,編譯器不會讓它通過。這個問題很難解決。你可以為這個函數(shù)選擇一個新名字,讓舊函數(shù)調用它,并將這個新增的checked exception(可控式異?!睫D換成一個unchecked exception(不可控異常:)。你也可 以拋出一個unchecked異常,不過這樣你就會失去檢驗能力。如果你那么做,你可以警告調用者:這個unchecked異常日后會變成一個checked異常。這樣他們就有時間在自己的代碼中加上對此異常的處理。出于這個原因,我總是喜歡為整個package定義一個superclass異常(就像java.sql的SQLException),并確保所有public函數(shù)只在自己的throws子句中聲明這個異常。這樣我就可以隨心所欲地定義異常,不會影響調用者,因為調用者永遠只知道那個更具一般性的superclass異常。
請問這段話是什么意思?

回答
編輯回答
巫婆

我用具體的代碼來解釋下吧
接口A,有方法X

public interface A {
    public void methodX() throws IOException;
}

在用戶模塊有這樣一段調用

public class ModuleUser{
    public void methodY(A a) throws IOException
    {
        a.methodX();
    }
}

現(xiàn)在要對方法X增加一個異常,變?yōu)椋?/p>

public interface A {
    public void methodX() throws IOException,DataFormatException;
}

這樣用戶模塊ModuleUser的方法Y就要修改,不修改,編譯就不會通過。

怎么樣解決呢?
方法1,新方法調用舊方法。(接口中不能新方調用舊方法,所以我改為抽象類)

public abstract class A {
    public void methodX() throws IOException
    {
        try {
            methodNewX();
        } catch (DataFormatException e) {
            throw new RuntimeException(e);
        }
    }
    
    public abstract void methodNewX() throws IOException ,DataFormatException;
}

方法2: 以拋出一個unchecked異常,unchecked就是編譯器不檢查的運行時異常。
如下

public interface A {
    public void methodX() throws IOException,RuntimeException;
}

這樣用戶代碼也不用改。

但這兩個方法都不好。

作者喜歡的做法是這樣的(也是推薦的方式)。
在包中定義自己的異常

public class MyException extends Exception {

}

接口一開始就寫成

public interface A {
    public void methodX() throws MyException;
}

用戶模塊就會是這樣的:

public class ModuleUser{
    public void methodY(A a) throws MyException
    {
        a.methodX();
    }
}

如果再遇到上面要加異常信息的情況
就為MyException創(chuàng)建一個子類,加接口A上,這樣用戶代碼就不用改,也能適配。

上面一段話大概就是想表達這個觀點。
因為這本書是國外人寫的,翻譯成中文,所以讀起來有點別扭。
英文原文是這樣的

There is one particular area with problems in changing interfaces in Java: adding an exception to the throws clause.

讀這本書,覺得不好理解的,就可試著看看英文原文。

2018年7月10日 19:49