Your SlideShare is downloading. ×
Javaプログラミング入門【第6回】
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Javaプログラミング入門【第6回】

353
views

Published on


0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
353
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Javaプログラミング入門 第5回
  • 2. 今日の講義 • 例外 • インターフェース
  • 3. 日常の『例外』とJavaの『例外』 • 普段の『例外』 ▫ 「魚は空を飛ばない。けど、トビウオは例外」 ▫ 規則に当てはまらないものを意味する • Java言語の『例外』 ▫ プログラムの誤りを検知し、適切なエラー処理を 行うための機構 ▫ 普段の『例外』とは異なる
  • 4. Java言語の例外 • 例外(exception) 1. 配列の長さを越えた添字で要素を参照した  ArrayIndexOutOfBoundsException 2. ファイルを開こうと思ったが、ファイルがな かった  FileNotFoundException 3. メソッドに与えられた引数が異常な値だった  IllegalArgumentException 4. オブジェクトをたくさん作りすぎてメモリが足 りなくなった  OutOfMemoryException
  • 5. 例外を起こしてみる public class ExceptionTest1 { public static void main(String[] args) { int[] myarray = new int[3]; System.out.println("代入します"); myarray[100] = 0; System.out.println("代入しました"); System.out.println("代入終了します"); } }
  • 6. 例外が発生すると後続の処理は行わな い • 「代入しました」「終了します」は表示されな かった →プログラムが myarray[100] = 0; で例外(ArrayIndexOfBoundsException)が発生 したため、処理が中断されたため • 例外が起きたことを「例外が投げられた」「例 外がthrowされた」と言う
  • 7. 例外をキャッチする • 例外の処理を行うことを「例外を受ける」「例 外をcatchする」と言う • 例外を正しくキャッチすることにより、後続の 処理を続行させることが出来る
  • 8. 例外をキャッチする例 public class ExceptionTest2 { public static void main(String[] args) { int[] myarray = new int[3]; try { System.out.println("代入します"); myarray[100] = 0; System.out.println("代入しました"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("代入できませんでした"); System.out.println("例外は" + e + "です"); } System.out.println("終了します"); } }
  • 9. 例外のイメージ try { 例外のスロー } catch (Exception e) { 例外のキャッチ }
  • 10. 投げられてるのはクラスではなくイン スタンス • ArrayIndexOutOfBoundsException ▫ クラス名 • 「 ~Exception を投げる」と言うが、実際に投 げられているのはクラスではなくインスタンス • catch (ArrayIndexOutOfBoundsException e)のe はインスタンスを受け取る変数
  • 11. 階層化されたメソッド呼び出しから投 げられる例外 public class ExceptionTest3 { public static void main(String[] args) { int[] myarray = new int[3]; try { System.out.println("代入します"); myAssign(myarray, 100, 0); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("代入出来ませんでした"); System.out.println("例外は" + e + "です"); } System.out.println("終了します"); } static void myAssign(int[] arr, int index, int value) { System.out.println("myAssignに来ました"); arr[index] = value; System.out.println("myAssignから帰ります"); } }
  • 12. 実行してみる
  • 13. コールスタック • メソッド呼び出しの積み重ねのことをコールス タック(call stack)と言う ▫ 「呼び出し(call)」「積み重なったもの(stack)」 • 例外が発生した場合、returnとは異なり、1つ前 のメソッドに戻るとは限らない。同じメソッド 内のcatch節に飛ぶかもしれないし、メソッドの 呼び出し元を遡って、初めて見つかったcatch節 にジャンプすることもある • メソッド呼び出しと例外の仕組みを理解してい ないと、プログラムの動きを見失うことになる
  • 14. メソッドの処理を中断しても大丈夫な のか? • やりかけの仕事を途中で放棄してプログラムは 破綻しないのか? ▫ やりかけの仕事を放棄しても、try文を終了する前 に、finallyブロックで終了処理を書くことが出来 る
  • 15. finallyブロックを使った例 public class ExceptionFinally { public static void main(String[] args) { System.out.println("Start"); try { int[] a = new int[3]; System.out.println("代入します"); a[3] = 123; System.out.println("代入しました"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("例外が発生しました " + e); } finally { System.out.println("finallyブロックです"); } System.out.println("End"); } }
  • 16. 代表的な例外処理の例 • 数への変換 ▫ 文字列を整数値に変換する際に入力された文字が 数値でなかった場合  NumberFormatException • ファイル処理 ▫ ファイルが存在しなかった場合  FileNotFoundException ▫ ファイルを読んだりクローズする時にエラーが発 生した場合  IOException
  • 17. NumberFormatException public class NumberTest { + e); public static void main(String[] args) { String numstr = "XYZ"; try { int val = Integer.parseInt(numstr); System.out.println("val = " + val); } catch (NumberFormatException e) { System.out.println("例外が発生しました " } } }
  • 18. 自分で投げる例外 throws new IOException(); • 予約語throwsの後に投げたい例外のインスタン スを記述することで、例外を投げることが出来 る
  • 19. APIライブラリのマニュアル public FileReader(String fileName) throws FileNotFoundException • FileNotFoundExceptionがthrows節によって表 現されている
  • 20. 例外の階層 Object Throwable Error Exception RuntimeException それ以外の Exception
  • 21. 例外の階層 • Throwable(throw + able):投げることが出来るク ラス ▫ Errorは、もはや動作を継続するのは期待できな い時に投げられるクラス ▫ Exceptionは、正しく例外処理を行って、動作が 継続することを期待するときに投げられるクラス  RuntimeException:実行中に起こり、コンパイラに よって前もってチェックされない例外  その他のException:コンパイラによって前もって チェックされる例外
  • 22. チェックされる例外ですべきこと • メソッドの中で throw new IOException(); と記述していた場合 1. メソッド内のcatch節でその例外をキャッチす ること 2. メソッドのthrow節でその例外を投げることを 宣言 • どちらか一方を必ずしなければならない
  • 23. メソッド内のcatch節でその例外を キャッチする void someMethod() [ try { ... throw new IOExcrption(); ... } catch (IOException e) { ... } }
  • 24. メソッドのthrow節でその例外を投げ ることを宣言 void someMethod() throws IOException { ... throw new IOExcption(); ... }
  • 25. 「チェックされる例外」の意味 • 例外は「投げっぱなしには出来ない」 • 例外はキャッチするか、キャッチしない場合は throwして上位のメソッドでキャッチして処理 を行わなければならない
  • 26. 「チェックされない例外」の意味 • 「いつどこで起こってもおかしくないような例 外」 ▫ いつ、どこで起きるかわからないので、チェック できない
  • 27. 例外の階層とcatch節 • 例外を正しくキャッチするには、例外自体の階 層を正しく理解する必要がある • 投げられた例外をキャッチするのは、一番早く マッチした例外
  • 28. マッチする例外 try { ... throw new IOException(); ... } catch (RuntimeException e) { ... } catch (IOException e) { // こちらが実行される ... } • IOExceptionはRuntimeExceptionの拡張クラスでは ないため、RuntimeExceptionのcatch節には入らな い
  • 29. 投げられた例外は親クラスを使って キャッチ出来る try { ... throw new IOException(); ... } catch (Exception e) { // キャッチされる ... } • ExceptionクラスはIOExceptionクラスの親クラ スなため、キャッチすることが出来る
  • 30. 例外を用いたプログラミングの注意点 • 例外を用いると、エラーが起きる場所とそのエ ラーを処理する場所を分けることが出来る • ただし、try文を注意深く作らなければ、例外が どこで発生しているかわからなくなる
  • 31. スタックトレース • printStackTraceを使うと、どこで例外が発生し たか見ることが出来る
  • 32. printStackTraceを使った例 public class ExceptionTest4 { public static void main(String[] args) { int[] myarray = new int[3]; try { System.out.println("代入します"); myAssign(myarray, 100, 0); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("代入出来ませんでした"); System.out.println("例外は" + e + "です"); e.printStackTrace(); } System.out.println("終了します"); } static void myAssign(int[] arr, int index, int value) { System.out.println("myAssignに来ました"); arr[index] = value; System.out.println("myAssignから帰ります"); } }
  • 33. finallyをうまく使う • finallyブロックは例外が投げられても、投げら れなくても、finallyブロックは必ず実行される • finallyブロックの中には必ず行うべき後始末を 記述する ▫ ファイルのクローズ処理、ネットワークのコネク ションクローズ処理など • finallyブロックの中にはreturn文を記述してはい けない
  • 34. メソッドのエラー通知法 1. 戻り値でエラーを示す ▫ jaav.io.InputStreamReaderクラスのread()メ ソッドでは、ファイルの終端にたどり着き読み 込みが出来なくなった場合は、-1を返す 2. 例外でエラーを示す ▫ java.io.DataInputStreamクラスのreadCharメ ソッドではIOException、EOEExceptionを返す 3. 別の方法でエラーを示す ▫ java.io.PrintWriterクラスはcheckErrorメソッドを 呼び出して調べる必要がある
  • 35. 例外クラスの自作 • ゲームのプレイヤーが死んだ場合に、 DeadPlayerException ▫ Exceptionクラスの子クラスとして作る • ハイスコアのファイルが読めない場合は、 HiScoreDataIOException ▫ IOExceptionの子クラスとして作る
  • 36. 演習1 • 次のようなプログラムを動かしていて、 method1~method3までのいずれかでException が発生したとする。例外がどのクラスから投げ られているかわかるように、mainメソッドを修 正しなさい
  • 37. ExceptionTest5.java public class ExceptionTest5 { public static void main(String[] args) { try { mehod1(0); mehod2(0); mehod3(0); } catch (Exception e) { System.out.println("例外:" + e); } } static void method1(int x) throws Exception{ } static void method2(int x) throws Exception{ } static void method3(int x) throws Exception{ } }
  • 38. 演習2 • 10の会場を求めるつもりで次のプログラムを記 述したが、実行時にStackOverflowErrorという 例外が投げられた。どうしてか。また、このプ ログラムをどう直せば10の階乗が求められる か。なお、10の階乗とは 10×9 ×8 ×7 ×6 ×5 ×4 ×3 ×2 ×1 のことである
  • 39. FactorialTest.java public class FactorialTest { public static void main(String[] args) { System.out.println(factorial(10)); } public static int factorial(int n) { return n * factorial(n -1); } }
  • 40. インターフェースとは • ここで学ぶインターフェースという単語は、 「人間とコンピュータのやりとりの約束事」 • インターフェースもクラスと同様参照型の一種 • インターフェースは、名前を持ち、フィール ド、メソッド、スーパーインタフェース、サブ インターフェースを持つ
  • 41. クラスとインターフェースの違い • インターフェースが持つフィールドは必ず定数 • インターフェースが持つメソッドは必ず抽象ク ラス(メソッドは実装されない) • インターフェースはインスタンスを作ることが できない
  • 42. インターフェースの定義 interface Lockable { boolean lock(); boolean unlock(); } • interface内で宣言されているメソッドはabstract がついていなくても自動的に抽象クラスとなる (メソッドの実装部分{}は記述できない) • インターフェースの名前にはRunnableのように -ableという言葉(接尾語)を付けることが多い
  • 43. インターフェースの実装 public class Kinko implements Lockable { @Override public boolean lock() { return false; } @Override public boolean unlock() { return false; } } • 「実装」というのは「実際に装備する」という意味
  • 44. extendsとimplementsの違い • 「クラスの拡張」extends • 「インターフェースの実装」implements • Kinkoクラスはextends節がないため、スーパー クラスはObjectクラスになる。KinkoでもObject のメソッドを使うことが出来る(継承)
  • 45. JewelBoxクラス(Boxクラスを拡張)を拡 張したLockableJewelBox public class LockableJewlBox extends JewelBox implements Lockable { @Override public boolean lock() { return false; } @Override public boolean unlock() { return false; } }
  • 46. クラス階層図 Lockableを実装 しているクラス Object Kinko Box JewelBox LockableJewelBox
  • 47. KinkoクラスとLockableJewelBoxクラス の違い • LockableJewelBoxは、JewelBox、Box、Object のメソッドをすべて継承している • LockableJewelBoxは、Lockableも実装している ので、lock、unlockメソッドも持つ • Kinkoクラスの親はObjectクラスのみ • クラス階層の上ではあまり関係がない ▫ 無関係なクラスでもimplements Lockableを宣言 することによって、「共通のメソッド」をプログ ラムで宣言することが出来る
  • 48. 例:DebugPrintableインターフェース • プログラム実行中にインスタンスの内容をデ バッグ出力する public interface DebugPrintable { void debugPrint(); }
  • 49. DebugPrintableインターフェースを実 装したMyNumberクラス public class MyNumber implements DebugPrintable { int a; public MyNumber(int a) { this.a = a; } @Override public void debugPrint() { System.out.println("MyNumberのインスタン ス:aの値は" + a + "です"); } }
  • 50. MyNumberクラスの動き MyNumber num = new MyNumber(123); とインスタンスを作ったとすると num.debugPrint(); は MyNumberのインスタンス:aの値は 123 です と表示される
  • 51. MyFileReaderクラス • DebugPrintableインターフェースを実装し、FileReaderクラス(ファイル読み込みを行うク ラス)を拡張する public class MyFileReader extends FileReader implements DebugPrintable { String filename = null; public MyFileReader(String filename) throws FileNotFoundException { super(filename); this.filename = filename; } @Override public void debugPrint() { System.out.println("MyFileReaderのインスタンス:ファイル名は" + filename + "です"); } }
  • 52. MyFileReaderクラスの動き MyFileReader reader = new MyFileReader("input.txt"); とインスタンスを作ったとすると reader.debugPrint(); の実行によって MyFileReaderのインスタンス:ファイル名は input.txt です と表示される
  • 53. クラス階層図 Object MyNumber Reader InputStreamReader FileReader MyFileReader
  • 54. インターフェース型の変数 • インターフェースはインスタンスを作ることが 出来ない DebugPrintable obj = new DebugPrintable(); ☓ DebugPrintable obj = new MyNumber(123); ○ MyNumberはDebugPrintableインターフェースを 実装しているので、MyNumberのインスタンスは DebugPrintable型の変数objに代入出来る
  • 55. MyFileReaderの場合 DebugPrintable obj = new MyFileReader(123); ○ 変数objはDebugPrintable型なので obj.debugPrint(); は呼び出す事ができるが、 obj.read() はコンパイルエラーになる(インターフェースで 定義されていないため) ((MyFileReader)obj).read(); とキャストすることで使用できるようになる
  • 56. メソッドの引数でインターフェースを 利用する public class MyInspector { static void inspect(DebugPrintable obj) { obj.debugPrint(); } } 引数で与えられたobjがDebugPrintableインター フェースを実装しているクラスであれば、そのイ ンスタンスのdebugPrintメソッドを呼び出すこと が出来る
  • 57. インターフェースのフィールド • インターフェースで宣言したフィールドは必ず 定数になる • DebugPrintableインターフェースに次のような フィールドを追加する ▫ ▫ ▫ ▫ NO_ERROR FILE_ERROR MEMORY_ERROR PREFIX
  • 58. インターフェースのフィールド public interface DebugPrintable { int NO_ERROR = 0; int FILE_ERROR = 1; int MEMORY_ERROR = 2; String PREFIX = "ERROR:"; void debugPrint(); } インターフェースで宣言されているフィールドは、 自動的にpublic static final になる
  • 59. スーパーインターフェース • インターフェースはクラスと同様に拡張するこ とが出来る public interface FastRunnable extends Runnable { void fastrun(); } FastRunnableはRunnableのサブインターフェー ス
  • 60. 多重継承とインターフェース • クラスはスーパークラスを1つしか持つことが出 来ない • MyMediaClass、MyReaderClass、 MyWriterClassという3つのクラスの性質を持つ MyReaderWriterClassを作りたいと思っても、3 つのクラスからメソッドやフィールドを継承す ることが出来ない
  • 61. 多重継承とインターフェース • インターフェースを使うことにより、擬似的に 多重継承を実現することが出来る • スーパークラスはMyMediaClassのみにし、あと はインターフェースを使った「メソッド継承」 に統一する • ただし、継承するのは名前のみで、実装は継承 しない
  • 62. インターフェースは複数実装出来る public interface MyReadable { void read(byte[] data); } public interface MyWritable { void write(byte[] data); } public class MyReaderWriterClass extends MyMediaClass implements MyReadable, MyWritable { @Override public void write(byte[] data) { } @Override public void read(byte[] data) { } }
  • 63. クラスとインターフェースの比較 クラス インターフェース インスタンス 作れる 作れない メソッド いろいろ 必ずpublic abstract フィールド いろいろ 必ずpublic static final スーパークラス 1つだけ 持てない スーパーインターフェー ス 複数指定可能 (implementsを使う) class A implements B, c { .... } 複数指定可能 (extendsを使う) interface X extends Y,Z { .... }
  • 64. 演習3 • クラスAlphaをスーパークラスに持ち、イン ターフェースとBetaとGammaを実装したpublic なクラスDeltaの宣言を記述しなさい。ただし、 クラスの内容は省略可
  • 65. 演習4 • 次のメソッドとフィールドを持つIconInfoとい うpublicなインターフェースを定義しなさい ▫ 引数はint型で仮引数の名前はiconType、戻り値の 型はImage型で、名前がgetIconであるメソッド ▫ 型はintで名前はICON_16x16、値は1であるフィー ルド ▫ 型はintで名前はICON_32x32、値は2である フィールド
  • 66. 演習5 • 以下のMyMediaPlayableインターフェースを拡 張して、MySoundPlayableという名前のサブイ ンターフェースを宣言しなさい。追加するメ ソッドは以下のgetSoundNameである ▫ String getSoundName();
  • 67. MyMediaPlayableインターフェース interface MyMediaPlayable { void play(); void stop(); void loop(); }
  • 68. 参考文献 • Java言語 プログラミングレッスン[第3版]下 ▫ 結城浩[著]