2004 -0228 ver 1.00 公開版 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃.&&&& **** %%%%.  JavaScript&Javaで目指そう!基本情報技術者試験  ┃ ┃&&&&&&******%%%%%%  http://www.yscon.co.jp/j/java/jmaga/      ┃ ┃'&┃&''*┃*''%┃%'      (C)2004 斎藤末広 jmaga@yscon.co.jp  ┃ ┗━┻━━┻━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ 前回の発行部数 7991部(まぐまぐ:6687 melma!:718 Pubzine:479             ティアラオンライン:18 めろんぱん:89) ★解除・登録 :http://www2.odn.ne.jp/~egu33/jmaga/java-maga.html ★バックナンバー :http://www.yscon.co.jp/j/java/jmaga/ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓  第3期 第1号(通巻46号) 2004/02/27  e玉(例外)を受けそこなうと,クラッシュ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛  プログラムを作成する上での注意事項:  WindowsXP, SDK(JDK) 1.4.2,IE 6.0 を前提としています。  「ファイルの拡張子を表示する」に設定してください。 ========================================================================= ☆お奨めメールマガジン  Jマガで,Javaを学習するときに,MS-DOSの知識があると便利です。また, マイクロソフトのWindos系のOSは,MS-DOSがベースとなっているため,トラブル 対応時に,MS-DOS の知識が大いに役立ちます。  MS-DOS を勉強するら次のメールマガジンがいいですよ。  メールマガジン「いざというときに役立つMS−DOS」  http://www.geocities.co.jp/Bookend-Hemingway/4963/column/dos/ ========================================================================= ▼Jマガ復活  みなさん,長らくお待たせしました。  Jマガを復活します。第2期は,予告のみで,できませんでした。申し訳あり ません。  第3期は,第2期の失敗をかてに,どんどん出していきたいと思います。  発行が調子にのるまで,あまり次号予告をせずに,出していきます。 ------------------------------------------------------------------------ ▼平成15年秋問題に,驚きの「例外」出題  基本情報処理技術者試験では,Javaの「例外」は出題されないと予想していま したが,なんと,問8,問12とも出題されてしまいました。  問題自体は,「例外」に対する知識がそれほど無くても解ける問題でしたが, はじめみた人にはかなり焦ったか思います。  今回は,その「例外」について解説します。 ------------------------------------------------------------------------ ▼その前に,jv.bat の設定  Java の SDK の 1.4.2 は,DOS プロンプト画面から,java クラス名 だけで, 実行できないようです。 以下のバッチファイルを利用して下さい。 jv.bat http://www.yscon.co.jp/j/java/jmaga/jsmp/j46/xEdama00.java jv.bat 内容は java -classpath . %1 %2 %3 の1行のみです。 実行するときは jv クラス名 ------------------------------------------------------------------------ ▼プログラムを止めるのは,簡単,0で割ればよい  まずは,サンプルを見て下さい。 例 j46-01 xEdama00.java ソース http://www.yscon.co.jp/j/java/jmaga/jsmp/j46/xEdama00.java 1: /* 2: 例外発生サンプル 0で割る 3: */ 4: public class xEdama00 { 5: public static void main(String[] xargs){ 6: for(int i=-3; i<= 3; i++){ 7: System.out.println(100/i); 8: } 9: } 10: } これを コンパイル後,jv.bat で実行すると J:\j46>jv xEdama00 J:\j46>java -classpath . xEdama00 -33 -50 -100 Exception in thread "main" java.lang.ArithmeticException: / by zero at xEdama00.main(xEdama00.java:7) となり,途中で停止します。 このプログラムは,100 / i で,i を,-3 から 3 まで,変えながら,順に計算 しようとしますが,100/ 0 を計算しようとしたところで,エラーとなり,停止し ます。 ------------------------------------------------------------------------ ▼ Exception の日本語は? 例外  上のプログラムの動作が中止したときに表示されたメッセージを再度みてみま しょう。 Exception in thread "main" java.lang.ArithmeticException: / by zero at xEdama00.main(xEdama00.java:7)  exception は,「例外」と訳されます。このメッセージは,0で割った(/ by zero) という,ArithmeticExcetion(算術例外) のエラーであったといことを教えてくれ ます。  Java では,プログラム上のこのようなエラーを,exception(例外)といいます。 ------------------------------------------------------------------------ ▼ トラブルを処理したら実行を継続可能  0で割るという,この例外事項をうまく処理したら実行が継続します。次の例 を見て下さい。 例 j46-02 xEdama01.java ソース http://www.yscon.co.jp/j/java/jmaga/jsmp/j46/xEdama01.java 1: /* 2: 例外発生サンプル 例外事項対応処理 3: */ 4: public class xEdama01 { 5: public static void main(String[] xargs){ 6: for(int i=-3; i<= 3; i++){ 7: try{ 8: System.out.println(100/i); 9: } 10: catch(ArithmeticException xedama){ 11: System.out.println("発生したエラー:" + xedama); 12: System.out.println("そのときの i は," + i); 13: } 14: } 15: } 16: }  エラーが発生しそうなところを,try{ } でくくり,発生したエラーの処理 を,catch( ){ } の中に書きます。try{ } catch( ){ } で,try-catch文といい ます。try { … } は,tryブロック(try節),catch { … }を, catchブロック(catch節)といいます。  これを実行すると J:\j46>jv xEdama01 J:\j46>java -classpath . xEdama01 -33 -50 -100 発生したエラー:java.lang.ArithmeticException: / by zero そのときの i は,0 100 50 33 なんとか最後まで実行しました。 さきほど,エラーが発生した箇所,100/0 のところで,xedama と「そのときの i は,0」と表示しました。 ------------------------------------------------------------------------ ▼ 投げられた「例外」は,ガラスの e玉  xEdama01 は,try{ } でプログラムの例外事項(エラー)を監視して,そこで, 例外事項が発生した場合,その例外事項をcatch して,処理をします。  Java では「例外事項」は,インスタンスして表します。上の例では,ゼロで割 るというというエラー情報を,インスタンスにつめて,投げだします。それを, catch で受取ります。  例外事項が発生したら「例外」を投げだし,それを,catch する  というのがJava風の言い方です。しかし,これだと,「例外を投げる」という 変な日本語になります。Jマガでは,例外事項(エラー)が発生したら,e玉が投げ 出されと,いうことにします。e玉は,ガラスで出来たカプセル玉をイメージして 下さい。e玉の中には,エラー情報が入ります。e玉は,xEdama00, xEdama01 を 例にすると,ArithmeticExceptionクラスのインスタンスです。  tryで監視していなければ,エラーが発生し,投げ出されて,だれも受け取って くれずに,e玉は,割れて,プログラムが終了します。これが,xEdama00 でした。  xEdama01 では,tryで監視して,投げ出されたe玉を catch し,エラー処理を して,続行しました。エラー処理といっても,xEdama01 でしたことは,エラー 内容,xedama を表示しただけです。 ------------------------------------------------------------------------ ▼ e玉(例外)の種類  e玉は,Throwable クラスとそれを継承した子クラスのインスタンスです。 Throwable クラス群の親子系統図 Object | +- Throwable -+- Exception -+- いっぱいある A群 | | | +- RuntimeException -- ArithmeticException等 |  いっぱいある B群 | |        +- Error - いっぱいある C群  xEdama00, xEdama01 の e玉は,B 群に属する ArithmeticExcetiopn クラスの インスタンスでした。 ------------------------------------------------------------------------ ▼ コンパイラが検査してくれる「チェック例外」 A群の e玉  上のA群のe玉は,登場する可能性があるときは,コンパイル段階でチェック され,そのe玉の try-catch を書かないと,コンパイルが出来ません。そのため ここに属する e玉は,「チェック例外」と呼ばれます。コンパイラーにチェック される例外という意味です。  ここには,画像ファイルを扱うときに,それが無かったとか,文字変換が失敗 したなど,プログラムのエラーというより,外部の状況次第のエラーがここに入 ります。ファイルを扱うメソッドにおいて,それが無かった場合の対応をきちん と書く必要があるということで,コンパイラーにチェックされます。  B群,C群に属する e玉は,コンパイルのときに,try-catchがあるかどうかは チェックされません。そのため「非チェック例外」と呼ばれます。  B群には,先に登場した,ゼロでのわり算のエラー,配列の要素を超えて,配列 を使おうとしたときのエラーなどが入ります。こちらは,必ず,try-catchをする とすると,すべてのわり算にそれが必要になり,実用的ではないということで, コンパイラーによってチェックされません。  xEdama00, xEdama01 の e玉は,B群のクラスのインスタンスでした。ですから xEdama00 のように,try 文がなくてもコンパイルができます。  C群は,通常のプログラム内で発生するエラーではなく,OSとJVMの間で発生 するエラーなどです。メモリー不足などが属します。こちらも,Java のプログラム 内でそれを処理するプログラムを書くことがありませんので,なくても,コンパ イルが通ります。  Java のプログラムで通常扱うのは,A群,B群に属するエラー事項です。 ------------------------------------------------------------------------ ▼ A群に属する例外事項「チェック例外」  では,A群に属する e玉をみてみましょう。  次のサンプルは,テキストファイルを一行ずつ読んで,表示するプログラムで す。 例 j46-03 xEdama02.java ソース http://www.yscon.co.jp/j/java/jmaga/jsmp/j46/xEdama02.java 1: /* 2: 例外発生サンプル IOException例 3: */ 4: import java.io.*; 5: 6: public class xEdama02 { 7: 8: public static void main(String[] xargs) { 9: 10: String xbuf =""; 11: 12: FileReader xfr = new FileReader("abc.txt"); 13: BufferedReader xbr = new BufferedReader(xfr); 14: 15: while((xbuf=xbr.readLine()) != null){ 16: System.out.println(xbuf); 17: } 18: 19: xfr.close(); 20: xbr.close(); 21: 22: } 23: }  このプログラムは,abc.txt ファイルを読み込んで表示しますので,もし, abc.txt ファイルがないとき,当然エラーになります。  このプログラムをコンパイルすると J:\j46>javac xEdama02.java xEdama02.java:12: 例外 java.io.FileNotFoundException は報告されません。 スローするにはキャッチまたは、スロー宣言をしなければなりません。 FileReader xfr = new FileReader("abc.txt"); ^ xEdama02.java:15: 例外 java.io.IOException は報告されません。スローする にはキャッチまたは、スロー宣言をしなければなりません。 while((xbuf=xbr.readLine()) != null){ ^ xEdama02.java:19: 例外 java.io.IOException は報告されません。スローする にはキャッチまたは、スロー宣言をしなければなりません。 xfr.close(); ^ xEdama02.java:20: 例外 java.io.IOException は報告されません。スローする にはキャッチまたは、スロー宣言をしなければなりません。 xbr.close(); ^ エラー 4 個 とコンパイルエラーがでます。  FileNotFoundException,IOException の例外事項が発生する可能性があるの で,その例外(e玉)を try-catch するプログラムを書かないと,コンパイラーが 許さないとと言っています。  xEdama00.java では,このようなコンパイルエラーがでませんでした。今回 は,このように,コンパイラーがチェックしますので,この種の例外事項を 「チェック例外」といいます。  FileNotFoundException は,IOException の子クラスですので,IOException の e玉を受け取れば,FileNotFoundException の e玉も受け取ることができます。 これは,子クラスのインスタンスは,親クラスのインスタンスとしても扱えると く原則によります。  では,次のサンプルプログラムでは,IOException の e玉を監視して,飛び出 したら,受け取るプログラムに変更します。 例 j46-04 xEdama03.java ソース http://www.yscon.co.jp/j/java/jmaga/jsmp/j46/xEdama03.java 1: /* 2: 例外発生サンプル IOExceptionを受取る例 3: */ 4: import java.io.*; 5: 6: public class xEdama03 { 7: 8: public static void main(String[] xargs) { 9: 10: String xbuf = ""; 11: 12: try{ 13: FileReader xfr = new FileReader("abc.txt"); 14: BufferedReader xbr = new BufferedReader(xfr); 15: 16: while((xbuf=xbr.readLine()) != null){ 17: System.out.println(xbuf); 18: } 19: 20: xfr.close(); 21: xbr.close(); 22: } 23: catch(IOException edama){ 24: System.out.println(edama); 25: } 26: } 27: }  これを実行すると,abc.txt があれば,その中身が表示されます。 もし,abc.txt がない場合 J:\j46>jv xEdama03 J:\j46>java -classpath . xEdama03 java.io.FileNotFoundException: abc.txt (指定されたファイルが見つかりません。)  とエラーメッセージが表示されます。 ------------------------------------------------------------------------ ▼ throw文 e玉を自分で投げる  e玉を自分で投げることもできます。その場合,うまく,catch をしないとプロ グラムは停止します。  投げる e玉は,好きな 例外クラスのインスタンスを投げられます。コンパイ ラがチェックする,チェック例外を投げると,その catch があるかどうか,コン パイラがチェックしてくれます。非チェック例外の e玉をを投げると,コンパイ ラは,チェックせず,実行時に,そのe玉が投げれて,そのとき,catch されない とプログラムは止まります。 次の xEdama04.java は,コンパイルはできますが,実行中に止まります。 1: /* 2: 例外発生サンプル 自分で,throw 非チェック例外 3: */ 4: public class xEdama04 { 5: public static void main(String[] xargs){ 6: for(int i=-3; i<= 3; i++){ 7: if(i!=0){ 8: System.out.println(100/i); 9: }else{ 10: throw new ArithmeticException("0で割るのは禁止"); 11: } 12: } 13: } 14: } 次の xEdama05.java は,コンパイルはできません。try-catch文が必要です。 1: /* 2: 例外発生サンプル 自分で,throw チェック例外 3: */ 4: public class xEdama05 { 5: public static void main(String[] xargs){ 6: for(int i=-3; i<= 3; i++){ 7: if(i!=0){ 8: System.out.println(100/i); 9: }else{ 10: throw new Exception("0で割るのは禁止"); 11: } 12: } 13: } 14: }  基本情報技術者試験平成15年秋午後問8,12は,この throw 文が登場しま した。非チェック例外のe玉が登場しています。 参考  基本情報技術者試験平成15年秋午後問8  http://www.rs.kagu.sut.ac.jp/~infoserv/j-siken/H15b2/pm08.html  基本情報技術者試験平成15年秋午後問12  http://www.rs.kagu.sut.ac.jp/~infoserv/j-siken/H15b2/pm12.html  問8は,宿題メール会員限定ページで解説予定です。 ------------------------------------------------------------------------ ▼ throws宣言 呼び出された側に投げる  例外事項が発生した場合,メソッド内でcatchをせずに,呼び出したメソッド に任せることができます。その場合,メソッド宣言のところで,throws宣言を をします。 1: /* 2: 例外発生サンプル throws宣言例 3: */ 4: public class xEdama06 { 5: public static void main(String[] xargs){ 6: for(int i=-3; i<= 3; i++){ 7: try { 8: System.out.println(xwari(100,i)); 9: } 10: catch(Exception xedama){ 11: System.out.println(xedama); 12: } 13: } 14: } 15: 16: static int xwari(int x, int y) throws Exception { 17: if(y != 0){ 18: return x/y; 19: }else{ 20: throw new Exception("0で割るのは禁止"); 21: } 22: } 23: }  8 行目で呼び出される xwari()は,Exception の e玉を投げる可能性がありま すので,7 行目で,tryしています。  xwariメソッドを宣言しているところ,16行目に,throws 宣言があります。 20行目には throw 文があります。  この throws 宣言を利用することで,メソッドは,自分を呼び出した側に, 自分の使い方で,こうするとエラーだよと教えることができます。 ------------------------------------------------------------------------ ▼ 著作権について  このメールマガジンで公開している,プログラムソースは,著作権を当方スタッ フが所有しますが,プログラムソースの利用は,原則,商用を含めて,再利用, 改変,発表を制限しません。どんどんご利用下さい。  質問コーナのプログラムソースは,著作権に問題がある場合があるかもしれま せん。原則を適用しません。再利用の許可をしません。  画像や音などの素材は,それぞれ著作権があります。著作者に承諾なしに再利 用はできません。  本文に関しては,斎藤末広が著作権を所有します。再利用に関しては,承諾を 必要とします。お問い合わせ下さい。 ------------------------------------------------------------------------ ▼アンケート(以下を返信してください)  この号のJマガに対するご意見をお待ちしています。ぜひ,ご返信下さい。 この号の内容 1 良かった 2 普通 3 良くなかった コメント,リクエスト,質問もお待ちしています。遠慮せずにどうぞ。