C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: javaの検査例外の処理が面倒です


(過去ログ 90 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■53703 / inTopicNo.1)  javaの検査例外の処理が面倒です
  
□投稿者/ yan (1回)-(2010/09/24(Fri) 15:45:44)

分類:[Java] 

2010/09/24(Fri) 15:48:22 編集(投稿者)
2010/09/24(Fri) 15:47:46 編集(投稿者)

普段は.NET(VB,C#)で開発をしています。
Javaの初歩的な基礎知識はありますが、業務でJavaを使用したことはありません。
今回Java(Android)で作業しているのですが、件名について質問いたします。

件名の通り、Javaの検査例外の処理が面倒です。

たとえばファイルをコピーする処理の場合、finallyのbr.close(),bw.close()でも検査例外が出るのでtry〜catchで囲まないとコンパイルエラーになります。

private void fileCopy(InputStream is , String filename ){
    BufferedReader br = null;
    OutputStream os = null;
    BufferedWriter bw = null;
    try { 
        br = new BufferedReader(new InputStreamReader(is));    
        os = openFileOutput(filename, MODE_PRIVATE);   
        bw = new BufferedWriter(new OutputStreamWriter(os));   
   
        String str;      
         while((str = br.readLine()) != null){      
            bw.append(str +"\n");     
        } 
         bw.flush();          
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {   
        try {
            br.close();
            bw.close();   	   
        } catch (IOException e) {
            e.printStackTrace();
        }          
    }  
}

fileCopyメソッドを呼び出す側では、ファイルの存在チェックを行ってからこのメソッドを呼び出しているので
FilNotFoundExceptionがもし発生しても何もしないですし、IOExceptionが発生しても何もできないです。
(.Netでは例外を出すコストもあるので、事前に検査できるものは検査しましょうって言われていたと思います。
なのでファイルの存在チェックは必ず行っています。その上で発生するFileNotFoundExceptionはキャッチしていません。)

.NETでは処理できる例外のみをキャッチして処理し、それ以外はApplication.ThreadExceptionで処理しています。
Javaでも検査例外を実行時例外でラップし再スローして、UncaughtExceptionHandlerで処理しようと思っています。

質問1
finallyをスッキリ書きたいのですが、以下のようなtry〜catchを2重にするサンプルがありました。
このような書き方は一般的ではないのでしょうか?
(あまりみたことがないけれど、他にスッキリ書ける方法がわかりません)
private void fileCopy(InputStream is , String filename ){
    BufferedReader br = null;
    OutputStream os = null;
    BufferedWriter bw = null;
    try { 
        try {
            br = new BufferedReader(new InputStreamReader(is));    
            os = openFileOutput(filename, MODE_PRIVATE);   
            bw = new BufferedWriter(new OutputStreamWriter(os));   
   
            String str;      
            while((str = br.readLine()) != null){      
                bw.append(str +"\n");     
            } 
            bw.flush();   
        } finally {   
            br.close();
            bw.close();   	   
        }  
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

質問2
実行時例外でラップし再スローするにあたって、以下のようなラップ例外を一つ一つ書かなければいけないのでしょうか?
その際のパッケージはどうするのがいいでしょうか?Exceptionパッケージに全部つめこんでも問題ないでしょうか?
FileNotFoundRuntimeException
IORuntimeException

質問3
Javaと.Netでは例外の取り扱いが違うのは理解しているつもりですが
.Netに合わせたようなこのような方法はおかしいですか?

引用返信 編集キー/
■53707 / inTopicNo.2)  Re[1]: javaの検査例外の処理が面倒です
□投稿者/ やじゅ (1743回)-(2010/09/24(Fri) 17:56:01)
やじゅ さんの Web サイト
No53703 (yan さん) に返信

質問の回答ではありませんが、下記のサイトを紹介しておきます。
.NETとJavaの例外処理の違い
http://blogs.msdn.com/b/nakama/archive/2009/01/09/net-java.aspx

引用返信 編集キー/
■53710 / inTopicNo.3)  Re[2]: javaの検査例外の処理が面倒です
□投稿者/ yan (2回)-(2010/09/24(Fri) 19:49:58)
やじゅさん

サイトの紹介ありがとうございます。
何度か読んだことのあるページだったのですが、もう一度読み直してみました。
javaではアプリケーションエラーは実行事例外。業務エラーは検査例外として扱うとありますので、
上記の場合のIOException、FileNotFoundExceptionは実行事例外にラップしてスローしても問題ないと思うのですが・・・自信がありません。
引用返信 編集キー/
■53786 / inTopicNo.4)  Re[3]: javaの検査例外の処理が面倒です
□投稿者/ 通りすがり (73回)-(2010/09/27(Mon) 11:29:55)
2010/09/27(Mon) 11:39:57 編集(投稿者)
2010/09/27(Mon) 11:31:56 編集(投稿者)

No53710 (yan さん) に返信

やじゅさんではないが
finallyをスッキリ書きたいとのことですが、メソッドにthrows 節を記載すればよいのでは?

> やじゅさん
>
> javaではアプリケーションエラーは実行事例外。業務エラーは検査例外として扱うとありますので、
> 上記の場合のIOException、FileNotFoundExceptionは実行事例外にラップしてスローしても問題ないと思うのですが・・・自信がありません。

RuntimeExceptionにするかについて
 Null参照や範囲外index値指定等と同じ「修正不可能な」エラーなのでしょうか?

自分ならはExceptionを継承した独自例外を定義します
(例外を捕捉しているか、コンパイル時にチェックされるため)

1.メソッドのthrows 節に独自例外を記載
 例外のcatchを行いExceptionを継承した独自例外を生成してthrowする
2.利用側メソッドのthrows 節に独自例外を記載
3.最終的にはUncaughtExceptionHandlerで捕捉する

独自例外は1つでもかまわないと思います
 独自例外に原因となった例外やメッセージを保持させる方式をとる

提示サイトの
Java 版ビジネスロジックのソースコード「赤色」箇所
throws DupilicateCustomerIDException に着目

メソッドのthrows 節は.Netにない言語仕様です

引用返信 編集キー/
■53808 / inTopicNo.5)  Re[4]: javaの検査例外の処理が面倒です
□投稿者/ yan (3回)-(2010/09/27(Mon) 17:07:06)
通りすがりさん
返信ありがとうございます。

以下のようなサイトを見つけました。

サルでもわかる 逆引きデザインパターン > 第4章 逆引きカタログ その他 > 実行時例外を標準的に使う 
http://www.nulab.co.jp/designPatterns/designPatterns4/designPatterns4-2.html
私も同じ考えです。
(検査例外をまったく使用しないわけではありません)




> 自分ならはExceptionを継承した独自例外を定義します
> (例外を捕捉しているか、コンパイル時にチェックされるため)
> 
> 1.メソッドのthrows 節に独自例外を記載
>  例外のcatchを行いExceptionを継承した独自例外を生成してthrowする
> 2.利用側メソッドのthrows 節に独自例外を記載
> 3.最終的にはUncaughtExceptionHandlerで捕捉する
> 
> 独自例外は1つでもかまわないと思います
>  独自例外に原因となった例外やメッセージを保持させる方式をとる
> 

すいません。よくわからないです。
ExExceptionはExceptionを継承した独自例外で書きなおしてみました。
public class MainActivity extends Activity {
	
     > 2.利用側メソッドのthrows 節に独自例外を記載
    throws節が書けません。
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//レイアウトの読み込み
		this.setContentView(R.layout.main);
		//filesフォルダにtest.txtが存在しなければ、res/raw/test.txtをコピーする。
		String filename = this.getFilesDir().getAbsolutePath() + "/test.txt";
		File file = new File(filename);
		if ( file.exists() == false ) {
			Resources res = this.getResources();
			try {
				fileCopy(res.openRawResource(R.raw.test),filename);
  			} catch (ExException e) {
			   //何もできないので、エラー画面へ遷移する。
			}			
		}	
	}
	
     > 1.メソッドのthrows 節に独自例外を記載
     >  例外のcatchを行いExceptionを継承した独自例外を生成してthrowする
     finally句がすっきり書けません。
	private void fileCopy(InputStream is , String filename ) throws ExException{
		BufferedReader br = null;
		OutputStream os = null;
		BufferedWriter bw = null;
		try { 
			try {
	        	br = new BufferedReader(new InputStreamReader(is));    
	            os = openFileOutput(filename, MODE_PRIVATE);   
	            bw = new BufferedWriter(new OutputStreamWriter(os));   
	   
	            String str;      
	            while((str = br.readLine()) != null){      
	            	bw.append(str +"\n");     
	            } 
	            bw.flush();   
			} finally {   
        		br.close();
				bw.close();   	   
			}  
		} catch (FileNotFoundException e) {
			throw new ExException(e);
		} catch (IOException e) {
			throw new ExException(e);
		}
	}
}

引用返信 編集キー/
■53811 / inTopicNo.6)  Re[5]: javaの検査例外の処理が面倒です
□投稿者/ 通りすがり (74回)-(2010/09/27(Mon) 18:39:58)
2010/09/28(Tue) 03:38:07 編集(投稿者)
2010/09/27(Mon) 19:11:45 編集(投稿者)
2010/09/27(Mon) 18:52:28 編集(投稿者)

■No53808 (yan さん) に返信
> 通りすがりさん
> 返信ありがとうございます。
> 
> 以下のようなサイトを見つけました。
> 
> サルでもわかる 逆引きデザインパターン > 第4章 逆引きカタログ その他 > 実行時例外を標準的に使う 
> http://www.nulab.co.jp/designPatterns/designPatterns4/designPatterns4-2.html
> 私も同じ考えです。
> (検査例外をまったく使用しないわけではありません)
> 
> 
> すいません。よくわからないです。
> ExExceptionはExceptionを継承した独自例外で書きなおしてみました。
> public class MainActivity extends Activity {
> 	
>      > 2.利用側メソッドのthrows 節に独自例外を記載
>     throws節が書けません。
> 	protected void onCreate(Bundle savedInstanceState) {
> 		super.onCreate(savedInstanceState);
> 		//レイアウトの読み込み
> 		this.setContentView(R.layout.main);
> 		//filesフォルダにtest.txtが存在しなければ、res/raw/test.txtをコピーする。
> 		String filename = this.getFilesDir().getAbsolutePath() + "/test.txt";
> 		File file = new File(filename);
> 		if ( file.exists() == false ) {
> 			Resources res = this.getResources();
> 			try {
> 				fileCopy(res.openRawResource(R.raw.test),filename);
>   			} catch (ExException e) {
> 			   //何もできないので、エラー画面へ遷移する。
> 			}			
> 		}	
> 	}

継承したメソッドを使用しているため、throws節が書けないということでしょうか?
であれば、RuntimeExceptionもありと思います
だだし、コール側で捕捉しわすれると、プログラムが即時停止します


最初の投稿でUncaughtExceptionHandlerで処理するつもりとありますが
どのクラスで実装するのでしょうか?

■AndroidのActivityクラスのonCreateメソッドなら下記でよいのでは?

 fileCopyメソッドにthrows IOExceptionを追記
 =>fileCopyメソッドをコールする側でcatchするコードが強制される

public class MainActivity extends Activity
  //
protected void onCreate(Bundle savedInstanceState) {
  try {
      //
      fileCopy(res.openRawResource(R.raw.test),filename);
  } catch (Exception e) {
      //何もできないので、エラー画面へ遷移する。
  }
}

private void fileCopy(InputStream is , String filename ) throws IOException
  try{
    //ファイルコピー処理
  } finally { 
    //
    if (br != null) br.close();
    if (bw != null) bw.close(); 
  }
}

引用返信 編集キー/
■53837 / inTopicNo.7)  Re[5]: javaの検査例外の処理が面倒です
□投稿者/ 通りすがり (75回)-(2010/09/28(Tue) 10:24:46)
No53808 (yan さん) に返信
> 通りすがりさん
> 返信ありがとうございます。
>
> 以下のようなサイトを見つけました。
>
> サルでもわかる 逆引きデザインパターン > 第4章 逆引きカタログ その他 > 実行時例外を標準的に使う
> http://www.nulab.co.jp/designPatterns/designPatterns4/designPatterns4-2.html
> 私も同じ考えです。
> (検査例外をまったく使用しないわけではありません)
>
>
>
>>自分ならはExceptionを継承した独自例外を定義します
>>(例外を捕捉しているか、コンパイル時にチェックされるため)
>>
>>1.メソッドのthrows 節に独自例外を記載
>> 例外のcatchを行いExceptionを継承した独自例外を生成してthrowする
>>2.利用側メソッドのthrows 節に独自例外を記載
>>3.最終的にはUncaughtExceptionHandlerで捕捉する
>>
>>独自例外は1つでもかまわないと思います
>> 独自例外に原因となった例外やメッセージを保持させる方式をとる
>>

Androidを前提に発言していませんでした
AndroidのonCreateメソッドなら

・fileCopyメソッドは例外をcatchしないで伝播させる
・実行継続不可かはコール側(onCreate)で判断する
・コール側(onCreate)で実行時例外に変換する

これによりfileCopyメソッドでのcatchコードが不要になります
初期処理で継続不可のエラーのため、実行時例外に変換して問題ないと思います


引用返信 編集キー/
■53870 / inTopicNo.8)  Re[6]: javaの検査例外の処理が面倒です
□投稿者/ yan (4回)-(2010/09/28(Tue) 17:40:26)

通りすがり さん
ありがとうざいます。大変よくわかりました。
教えていただいた方法で実装してみようと思います。


やっぱり、この方法は一般的ではないですか・・・?

サルでもわかる 逆引きデザインパターン > 第4章 逆引きカタログ その他 > 実行時例外を標準的に使う
http://www.nulab.co.jp/designPatterns/designPatterns4/designPatterns4-2.html

引用返信 編集キー/
■53949 / inTopicNo.9)  Re[7]: javaの検査例外の処理が面倒です
□投稿者/ 通りすがり (76回)-(2010/09/30(Thu) 15:27:18)
No53870 (yan さん) に返信
>
> 通りすがり さん
> ありがとうざいます。大変よくわかりました。
> 教えていただいた方法で実装してみようと思います。
>
>
> やっぱり、この方法は一般的ではないですか・・・?
> ↓
> サルでもわかる 逆引きデザインパターン > 第4章 逆引きカタログ その他 > 実行時例外を標準的に使う
> http://www.nulab.co.jp/designPatterns/designPatterns4/designPatterns4-2.html
>
サンプルコードはプログラムで回復できない検査例外(DB接続失敗)
なのでRuntimeExceptionにして問題ない例と思います

しかし、コードが簡潔になるという旨の記載がありますが
それを理由として採用すべきではありません

今回はAndroidのpublicメソッドでExceptionをcatchにすれば、filecopyメソッドをすっきりさせることが可能なので、
そこまでやる必要はないと思います


引用返信 編集キー/
■53969 / inTopicNo.10)  Re[8]: javaの検査例外の処理が面倒です
□投稿者/ yan (5回)-(2010/10/01(Fri) 07:41:52)
通りすがり さん

> しかし、コードが簡潔になるという旨の記載がありますが
> それを理由として採用すべきではありません
コードが簡潔になるという理由だけで採用しようと思っていました。

教えていただいた方法で実装します。
ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -