try-catch 文で、Exception を最後にcatch文を書く前に捕捉したい例外のcatch文を
たくさん記述することがある。。。
for文の中にあったり、if のTHEN と ELSE にこれがあったりなどと記述して
しまった場合に、後から嫌になるが、急いでコードを書く時など仕方なく書いてしまう
ことがあった。何とか記述を減らすことができないか。。。
先ずはインタフェースと抽象クラス
// 各Exception 捕捉後の処理はこれを実装して用意する
public interface ExceptDealer{
/**
* AbstractExceptCatcher の parseExcept 実行の中で呼ばれる。
* @param <T> catch文の中で与えた任意のデータGenerics
* @param th Throwable
* @param nest Exception階層、0からカウント
* @param ts catch文の中で与えた任意のデータ(省略可)
* @return getCause() で元のThrowable を求めないか?
* true=これ以上のThrowableを解析しない
*/
public <T> boolean call(Throwable th,int nest,T...ts);
}
---------------------------------------------------------------------
import java.util.Map;
import com.google.inject.Inject;
public abstract class AbstractExceptCatcher{
@Inject private Map<String,ExceptDealer> _exceptMap;
@Inject private ExceptDealer _unknownExcept;
// try-catch(Exception e) 文、Exception 捕捉で実行する
// T は、catch文の中から指定する任意のデータ
public <T> void parseExcept(Throwable t,T...ts){
Throwable x=t;
for(int nest=0;x != null;x=x.getCause(),nest++){
String key = x.getClass().getName();
if (this._exceptMap.containsKey(key)){
if (this._exceptMap.get(key).call(x,nest,ts)) break;
}else{
this._unknownExcept.call(x,nest,ts);
}
}
}
}
Google guice インジェクトさせるための Module を用意して、
対応させたい Exception に対するExceptDealer インスタンスをバインドする
ように用意する→これは状況に応じて作成することになる。
→バインド定義を用意するのが、Exceptionに対応するコーディングである。
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.MapBinder;
public class ExceptModule extends AbstractModule{
/*
* @see com.google.inject.AbstractModule#configure()
*/
@Override
protected void configure(){
// AbstractExceptCatcher の 例外Map をバインド
MapBinder<String,ExceptDealer> mapbinder
= MapBinder.newMapBinder(binder(),String.class,ExceptDealer.class);
mapbinder.addBinding(NumberFormatException.class.getName()).to(NumberFormatDealer.class);
mapbinder.addBinding(SQLException.class.getName()).to(SQLExceptDealer.class);
:
// AbstractExceptCatcher の ExceptDealer unknownExcept(想定外の例外処理)バインド
binder().bind(ExceptDealer.class).to(UnknownDealer.class);
}
}
使用される try-catch 文は、例として、
public class Sample extends AbstractExceptCatcher{
:
try{
:
:
}catch(Exception e){
super.parseExcept(e,data);
}finally{
;
}
:
}
-------------------------------------------------------
// ExceptDealer 実装クラス
public class SQLExceptDealer implements ExceptDealer{
/* (非 Javadoc)
* @see ExceptDealer#call(java.lang.Throwable, int, T)
*/
@Override
public <T> boolean call(Throwable th,int nest,T...ts){
System.out.println("##SQLExceptDealer : getName = "+th.getClass().getName());
System.out.println("##SQLExceptDealer : getMessage = "+th.getMessage());
System.out.println("##SQLExceptDealer : nest = "+nest);
System.out.println("##SQLExceptDealer : ts.length = "+ts.length);
for(int n=0;n < ts.length;n++){
System.out.println("##SQLExceptDealer : ts["+n+"] = "+(String)ts[n]);
}
th.printStackTrace();
return true;
}
}