例外処理 Exception Handling • • • • • • • 例外(exception)とは何か 例外処理(exception handling)とは何か メソッドの実行時基本流れ図 例外処理の基本構造 – try/catch/finally blocks Error/Exception/Runtime_Exception Throwableクラスと例外クラスの定義 例外オブジェクト:例外スロー(throws, throw) 例外(exception)とは何か (What is the exception?) (1)日常の例外 例外というのは、規則(規律)をまもらないということです。 例えば、私は毎日6時に起きます。けれども今週の日曜日は例外です。 (2)Java言語の例外 Java言語の例外は、Java言語の規則をまもらないのことです。 例えば、1) 配列の長さを超えた添え字で要素を参照しょうとした。 int a[] = new int[3]; //aの添字は、0から2までの整数です。 a[6] = 7; Golden rule: errors occur • コンパイル時エラー Errors in compile =>ArrayIndexOutOfBoundsException L61 • プログラムの実行時エラー(致命) 2) 割り算の分母は0になる場合。 Errors in program execution -- serious error, con not recover • プログラムの実行時例外(修復できる) =>ArithmeticException L62 Exceptions in program execution -- not serious error, can recover 3) ファイルをオープンしようとしたが、ファイルがない。 =>FileNotFoundException Java言語の例外の例 (例外処理なし) Example of Java exception without exception handling 配列の範囲を超える ゼロによる割り算 public class arrayTest { public class DivideByZero { public static void main(String[] args) { public static void main(String[] args) { int[ ] a = new int[3]; System.out.println( quotient(3, 5)); System.out.println("a[2]に代入する"); System.out.println( quotient(3, 0)); a[2] = 8; System.out.println( quotient(5, 6)); System.out.println("a[2]に代入した"); } System.out.println("a[3]に代入する"); public static double quotient(int bunshi, int bunbo) { a[3] = 5; return (double) bunshi / bunbo; System.out.println("a[3]に代入した"); } System.out.println("終了します"); } } } 実行結果:L61 ここで例外 (配列の範囲を越えた) が起きる ここで例外 実行結果:L62 (ゼロによる割り算) が起きる 例外処理 Exception handling 例外処理とは、プログラム実行中のエラーを通知し、適切なエ ラー処理が出来るようにする機構です。 (必ずしもエラーだけでなく、例外的な処理に利用されることも) int[ ] a = new int[3]; a[2] = 8; //ok a[3] = 5; //例外(ArrayIndexOutOfBoundsException) // が発生する。 例外処理をされると クラス 例外が起きる かも知れない範 囲をtry{ }で囲む 例外処理の プログラム ArrayIndexOutOfBoundsException int[ ] a = new int[3]; のインスタンスがスローされる try { .... キャッチする a[3] = 5; 例外のクラス .... } catch (ArrayIndexOutOfBoundsException e) { キャッチした System.out.println("例外" + e + "です"); 例外オブジェクト } が入る .... メソッドの実行時基本流れ図 メソッドの実行時エ ラーがないとメソッド が本流によって実行 されます。 method start エラーがある エラーなし With error 例外オブジェクトの生成とスロー (throw) 例外をRuntime Systemへ届ける No error 本流 Runtime System error 例外処理のは三つの ステップがある。 • 例外オブジェクトのスロー exception • 例外のキャッチ 誰がこの例外を処理するを決める • 例外の処理コード 例外のキャッチ (catch) 決められないの場合 method end 例外処理のコード Program end or Next method Runtime Systemで誰 がこの例外を処理す ることを決められない とプログラム/メソッド が中断されます。 例外処理の基本構造 (Exception handling mechanism) try-catch-finally try{ 例外オブジェクトのスロー(投げる) no exception with exception } メソッドで、 •try { .... }の範囲を実行中にスローされた例外を catch (... ) {.... }の(... )でキャッチして{.... }で処理する。 •例外がスローされなかった場合はcatch (... ) {.... }を スキップ。 •一つのtryブロックに対しでは、0個以上catch ブロークを置きます。 •finallyブロックはオプションです。そこにはリソース を解放するためのコードを入れて置くのに最適な場所 です。 catch(exception1 e){ 例外1の処理 } catch(exception2 e){ 例外2の処理 } …… finally{ リソースの解放 } Java言語の例外処理の例(Example of exception handing) public class exceptionTest{ public static void main(String[] args) { int[ ] a = new int[3]; try { System.out.println(“a[2]に代入する”); a[2] = 8; (配列の範囲を越えた) System.out.println("a[2]に代入した"); がスローされる。 System.out.println(“a[3に代入する”); a[3] = 5; キャッチした例 外オブジェクトを 出力する ここで例外オブジェクト throw System.out.println("a[3]に代入した"); } catch (ArrayIndexOutOfBoundsException e) { handling System.out.println("例外" + e + "です"); } catch (Exception e) { 例外がスキップ System.out.println("Exception" + e + "です"); ここで例外オブジェクト (配列の範囲を越えた) をキャッチする。 catch } finally { System.out.println("finally"); } System.out.println("終了します"); } } 実行結果: L61, L62 Throwableクラスと例外クラスの定義 Object public class Throwable extends Object{ public Throwable(); public Throwable(String message); Throwable public String getMessage(); public void printStackTrace(); Exception …… error … } … Runtime Exception public class Error extends Throwable{ public Error(); public Exception(); public Error(String s); public Exception(String s); } … public class Exception extends Throwable{ } Other Exception – checked exception: must be caught and handled ClassNotFoundException RuntimeException – unchecked exception: may or may not be caught and handled …… IOException ArithmeticException AWTException …… IndexOutOfBoundsException public class DivideByZeroException extends Exception{ ArrayIndexOutOfBoundsException StringIndexOutOfBoundsException public DivideByZeroException() { super(“Attempted to divide by zero”);} NegativeArraySizeException …… } ArrayIndexOutOfBoundsException Runtime 例外クラスの例 java.lang.Object | +--java.lang.Throwable | +--java.lang.Exception ArrayIndexOutOfBoundsException() Constructs an ArrayIndexOutOfBoundsException with no detail message. ArrayIndexOutOfBoundsException(int index) | +--java.lang.RuntimeException | +--java.lang.IndexOutOfBoundsException Constructs a new ArrayIndexOutOfBoundsException class with an argument indicating the illegal index. ArrayIndexOutOfBoundsException(String s) | +--java.lang.ArrayIndexOutOfBoundsException try { public String getMessage() int a[] = new int[2]; Returns the errort message string of this throwable object. a[4] = 10;; public void printStackTrace() } catch (ArrayIndexOutOfBoundsException e) { System.out.println("exception: " + e.getMessage()); e.printStackTrace(); } Constructs an ArrayIndexOutOfBoundsException class with the specified detail message. Prints this Throwable and its backtrace to the standard error stream. throws節とthrow文 throws節を使って、メソッドは指定した例外(オブジェクト)をスローする(生成す る)可能性があるという宣言。 メソッドの中に、throw文で例外をスローします。 DivideByZeroException を宣言します public class DivideByZeroException extends Exception{ unchecked – ErrorとRuntimeExceptionのsub クラス checked – 自分定義の例外クラス public DivideByZeroException() { super(“Attempted to divide by zero”);} コンストラクタ } public double quotient(int numerator, int denominator) throws DivideByZeroException { if (denominator == 0) throw new DivideByZeroException(); return (double) numerator / denominator; } 例外は二種類: unchecked exception クラスは、メソッドに throws節でこの例外をスローする可能性があ るという宣言することが必要ない。 checked exception クラスは、メソッドにthrows 節でこの例外をスローする可能性があるとい う宣言することが必要です。 このメソッドには DivideByZeroExceptionをス ローする可能性があるという 宣言 DivideByZeroExceptionを ここでスローします 例外のキャーチと処理 (Example of exception handling) public class DivideByZero { public static void main(String[] args) { try { System.out.println( quotient(3, 5)); 実行結果: L65 メソッド quotient()を呼 び出し System.out.println( quotient(3, 0)); System.out.println( quotient(5, 6)); } ここでキャッチ される このメソッドは catch (DivideByZeroException e) { System.out.println( e); キャッチした例外オ ブジェクトを出力する } DivideByZeroExceptionをス finallyブロック なくでもよい ローする可能性があるという 宣言 finally{System.out.println( “Finished !”);} } public double quotient(int numerator, int denominator) DivideByZeroExceptionを throws DivideByZeroException { if (denominator == 0) ここでスローします public DivideByZeroException() return (double) numerator / denominator; } を宣言します public class DivideByZeroException extends Exception{ throw new DivideByZeroException(); } DivideByZeroException { super(“Attempted to divide by zero”);} } 課題 (Exercise) 1 y = f(x) = 1/log(2x²-5x+2) for x=0~9を計算して、y[10]の 配列の中に結果を格納するアプレットのプログラム (example)が左に与えられている。プログラムとそれに連 なったHTMLファイルをタイプした後、コンパイルして実 行せよ。テキストフィールドに0~9の数字を入力し、アプ レットに何が表示されるのかを確認せよ。0未満、もしく は9以上の数字を入力したとき、MS-DOSウィンドウに どのような例外メッセージが表示されるか?例外が起 こったとき、ArrayIndexOutOfBoundsExceptionを try/catchブロックを使ってメッセージ “You must enter an integer from 0 to 9”が表示されるようにせよ。 2 整数以外の文字を入力したとき、どのような例外メッ セージがMS-DOSウィンドウ上に表れるか?例外が 起こったとき、try/catchブロックを使用して NumberFormatException をハンドルし、“You must enter an integer. Other characters are illegal”というメッセージを 表示させよ。 3 "1"を入力したとき、特殊文字が表示される。これはlog() 関数の変数が負の値であるためである。レクチャーノー トのDivideByZeroExceptionクラスを 参照して、このタイプの例外と一致する例外クラス logOfNegativeValueを定義せよ。またメソッド(int x){...} で例外をスローせよ。前述のプログラムの例外をハンド ルせよ、またそれに対応する例外メッセージ "Unable to calculte the logarithm for a negative value"を示せ。 import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.text.DecimalFormat; public class example extends Applet implements ActionListener { private Label p1; private TextField input; private int x; private double y[] = new double[10]; public void init() { p1=new Label("Enter a number (0 to 9)"); add(p1);input = new TextField(10); input.addActionListener(this); add(input); } public void paint(Graphics g) { DecimalFormat precision2 = new DecimalFormat("#.00"); int xx= 70; g.drawString("y[0~9]: ", 20, 50); for(int i=0; i<y.length; i++) { g.drawString(precision2.format(y[i])+" ",xx,50); xx+=30;} } public void actionPerformed(ActionEvent e) { DecimalFormat precision2 = new DecimalFormat("#.00"); x = Integer.parseInt(input.getText()); y[x]= f(x); showStatus("y["+x+"] = f("+x+")="+ precision2.format(y[x])); input.setText(""); repaint(); } public static double f(int x) { return 1.0/(double)(Math.log(2*x*x-5*x+2)); } } <html> <applet code="example.class" width=450 height=100> </applet> </html> Exercise 1 Give the left applet program that calculates y = f(x) = 1/log(2x²-5x+2) for x=0~9, and puts the results into an array y[10]. Type the program and the associative HTML file, compile and run it. Input number 0 ~9 in the text filed and watch what will be shown in the applet. When you input a number less than 0 or greater than 9, what exception messages are displayed in your MS-DOS window? Handle this ArrayIndexOutOfBoundsException using try/catch blocks and show a message, “You must enter an integer from 0 to 9”, when the exception occurs. 2 When you input a character(s) which is not an integer, what exception messages are displayed in your MS-DOS window? Handle this NumberFormatException using try/catch blocks and show a message, “You must enter an integer. Other characters are illegal”, when the exception occurs. 3 When you input ‘1’, a special symbol will be shown. This is because the variable of the log( ) function is a negative value. Define an exception class corresponding to this type of exception by referring the DivideByZeroException class in the lecture note, and throw the exception in the method f(int x) { … }. Handle the exception in the previous program, and show the corresponding exception message. import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.text.DecimalFormat; public class example extends Applet implements ActionListener { private Label p1; private TextField input; private int x; private double y[] = new double[10]; public void init() { p1=new Label("Enter a number (0 to 9)"); add(p1);input = new TextField(10); input.addActionListener(this); add(input); } public void paint(Graphics g) { DecimalFormat precision2 = new DecimalFormat("#.00"); int xx= 70; g.drawString("y[0~9]: ", 20, 50); for(int i=0; i<y.length; i++) { g.drawString(precision2.format(y[i])+" ",xx,50); xx+=30;} } public void actionPerformed(ActionEvent e) { DecimalFormat precision2 = new DecimalFormat("#.00"); x = Integer.parseInt(input.getText()); y[x]= f(x); showStatus("y["+x+"] = f("+x+")="+ precision2.format(y[x])); input.setText(""); repaint(); } public static double f(int x) { return 1.0/(double)(Math.log(2*x*x-5*x+2)); } } <html> <applet code="example.class" width=450 height=100> </applet> </html> 課題 • arrayIndexOutOfBoundExceptionを自分で定義して次のようなJav aアプレットを作成せよ。自身で作成した arrayIndexOutOfBoundExceptionの例外を備えさせ、TextFieldに 10個の整数を入力し、それを配列に格納するようなアプレット。 ex1 • devideByZeroExceptionを自身で定義し(レクチャーノートの 例を修正して分母を整数型でなくフロート型を扱えるように する)、次のようなJavaアプレットを作成せよ。2つの TextFieldにそれぞれフロート、もしくは整数型の数値を入力 し、割り算の計算をさせる。 ex2 課題 • Define your own arrayIndexOutOfBoundException. Make a Java applet to input 10 integers from TextField, store the integers in an array with considerations of handling exception using your own defined arrayIndexOutOfBoundException. ex1 • Define your own divideByZeroException (modify the example in today’s lecture note so that a denominator has a float type rather than integer type ). Make a Java applet that is able to input two numbers with float or integer type from two TextField, and do calculation of division (refer to the textbook fig. 12.1). ex2
© Copyright 2025 ExpyDoc