Back To Main

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┃ ◆Javaで珈琲ブレイク vol.007 前編◆
┃……………………………………………………………………………………………
┃ [不定期] まぐまぐ ID=0000088576 Melma! ID=m00061296
┃……………………………………………………………………………………………
┃ 今回からご覧になる方は、バックナンバーもご活用下さい
┃ http://www.melma.com/mag/96/m00061296/
┃ http://backno.mag2.com/reader/Back?id=0000088576
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

------------------------------------------------------------
◆◇◆◇◆ 在宅パソコンオペレーター大募集!! ◆◇◆◇◆
★時給⇒2,000円 年齢/22歳〜55歳(学生不可)★サイドワーク可
【仕事】自宅のパソコンでオペレーション業務(業務用ソフトのサポート)
【条件】パソコン(Windows限定)メール出来る方。初心者指導いたします。
【問合は】電話03-6221-1465 (株)プログレ採用係 bosyuu@rex-go.com
------------------------------------------------------------


◆目次◆

■前回の解答
■BankAccount.java
■BankAccountTest.java
■BankAccountExceptionTest.java
■BankAccountMainExceptionTest.java
■BankAccountTryCatchExceptionTest.java
■ランタイムException (Runtime Exception)
■BankAccountRuntimeException.java
■RuntimeExceptionクラス


皆さん、こんにちは。

Mr.Hackです。やっと、ファイナルも終わり、ほっと一息です。今セメは本当に充実していて学ぶことがたくさんありました。特にソフトウェア工学のクラスで習ったことは、はこれからのMr.Hackのプログラムスタイルに多大に影響していくと思っています。折を見てMr.Hackが習ったことをご紹介していきますのでおたのしみに。ところで、上記の時給2000円っていいですね。Mr.Hackも日本にいた頃バイトをしていましたが、2000円もらえるってなかなかなかったような気がします。日本にいたらMr.Hackが電話してるかもしれません・・・。

さて、今週もがんばっていきましょう。まずは、前回の解答からです。

■前回の解答
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Question 6 の答え

以下は、BankAccountクラスと、それをテストするBankaccountTestクラスのサンプルです。

■BankAccount.java
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━ ここから ━━━━━━━━━━━━━━━━━━
/**
* バンク預金口座クラス。顧客の口座の出し入れ、残高
* 照会をおこなう(通貨単位:円)。預入引き落とし時、
* Precondition(条件)をチェックし、条件に合わない場合は、
* 例外を発生させる。残高をゼロとするデフォルトのコンストラクタ、
* 預金額をセットできるコンストラクタがある。また、一度に引き出せる上限は
* 2万円、一度に預金できる上限は10万円としてある。
*
* 例:
*
* BankAccount account = new BankAccount(2000);
* try {
* account.deposit(1000);
* account.withdraw(500);
* }
* catch (Exception e) {
* Sytem.out.println("例外が発生しました:" + e.getMessage());
* }
* double currentBalance = account.getBalance();
*
* 2000円を口座開設時預金し、1000円を預金後、600円を引き出して、現在の残高400円
* をcurrentBalanceに保持する。
*
* @author Mr.Hack
*/
public class BankAccount {

/**
* 口座の残高
*/
private double balance;
/**
* 一度に預け入れる上限額
*/
private final double MAX_DEPOSIT_AMOUNT = 100000;
/**
* 一度に引き落とせる上限額
*/
private final double MAX_WITHDRAW_AMOUNT = 20000;

/**
* 残高をゼロにセットするデフォルトコンストラクタ。初期化時、
* 残高をゼロにセットする。
*
*/
public BankAccount() {
this(0);
}

/**
* amount分を残高としてセットするコンストラクタ。初期化時(新しい口座作成時)、
* 預金額を残高としてセットする。
*
* @param amount 口座に預け入れる金額(預金)
*/
public BankAccount(double amount) {
this.balance = amount;
}

/**
* amount分を預金として口座に預ける。amountがゼロかマイナスの時、一度に預ける
* 上限金額を上回った時、例外を発生させる。
*
*
* @param amount 口座に預け入れる金額(預金)
* @exception Exception amountがゼロかマイナスの場合、定められた一度に預金できる
* 金額を上回った場合、例外発生。
*/
public void deposit(double amount) throws Exception {
if (amount <= 0) {
throw new Exception("入力した金額は0かマイナスです。amount: " + amount);
}
if (amount > MAX_DEPOSIT_AMOUNT) {
throw new Exception("一度に入金できる額の上限は" + MAX_DEPOSIT_AMOUNT + "です");
}
this.balance += amount;
}

/**
* amount分の金額を引き出す。amountがゼロかマイナスの時、引き落とし金額が残高を上回った時、
* あるいは、一度に引き出せる上限金額を上回った時、例外発生。
*
* @param amount 引き出す金額
* @exception Exception amountがゼロかマイナスの場合、引き出し額が残高を上回った場合、
* または、一度に引き出せる金額を上回った場合、例外発生
*/
public void withdraw(double amount) throws Exception {
if (amount <= 0) {
throw new Exception("入力した金額は0かマイナスです。amount: " + amount);
}
if (balance < amount) {
throw new Exception("残高を超えています");
}
if (amount > MAX_WITHDRAW_AMOUNT) {
throw new Exception("一度に引き落としできる額の上限は" + MAX_WITHDRAW_AMOUNT + "です");
}
this.balance -= amount;
}

/**
* 現在の残高を戻り値として返す。
*
* @return balance 口座にある現在の残高
*/
public double getBalance() {
return this.balance;
}


/**
* 現在の残高を戻り値として返す。 メソッド名が不適切なため、getBalance()に入れ替わり。
*
* @return balance 口座にある現在の残高
*/
public double getBlance() {
return this.balance;
}
}
━━━━━━━━━━━━ ここまで ━━━━━━━━━━━━━━━━━━


■BankAccountTest.java
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━ ここから ━━━━━━━━━━━━━━━━━━
/**
* BankAccountをテストするクラス
*
* @author Mr.Hack
* @version 1.0815
*/
public class BankAccountTest {
/**
* deposit()、withdraw(), getBlance()メソッドを
* それぞれテストする。
*/
public static void main(String[] args) throws Exception {

BankAccount account = new BankAccount();

// deposit()メソッドテスト
System.out.println("deposit()テスト");
/** マイナス引数テスト 引数-1で例外を発生させる */
try {
account.deposit(-1);
System.out.println("マイナス引数テスト失敗。例外発生できず");
}
catch (Exception e) {
System.out.println("マイナス引数テスト成功。例外:" + e.getMessage());
}
/** ゼロ引数テスト 引数0で例外を発生させる */
try {
account.deposit(0);
System.out.println("ゼロ引数テスト失敗。例外発生できず");
}
catch (Exception e) {
System.out.println("ゼロ引数テスト成功。例外:" + e.getMessage());
}
/** 上限金額超過引数テスト 引数100001で例外を発生させる */
try {
account.deposit(100001);
System.out.println("上限金額超過引数テスト失敗。例外発生できず");
}
catch (Exception e) {
System.out.println("上限金額超過引数テスト成功。例外:" + e.getMessage());
}

// withdraw()テスト
System.out.println("");
System.out.println("withdraw()テスト");
/** マイナス引数テスト 引数-1で例外を発生させる */
try {
account.withdraw(-1);
System.out.println("マイナス引数テスト失敗。例外発生できず");
}
catch (Exception e) {
System.out.println("マイナス引数テスト成功。例外:" + e.getMessage());
}
/** ゼロ引数テスト 引数0で例外を発生させる */
try {
account.withdraw(0);
System.out.println("ゼロ引数テスト失敗。例外発生できず");
}
catch (Exception e) {
System.out.println("ゼロ引数テスト成功。例外:" + e.getMessage());
}

/** 上限金額超過引数テスト 引数20001で例外を発生させる */
try {
account.deposit(50000);
account.withdraw(20001);
System.out.println("上限金額超過引数テスト失敗。例外発生できず");
}
catch (Exception e) {
System.out.println("上限金額超過引数テスト成功。例外:" + e.getMessage());
}
/** 残高超過引数テスト 1000円入金後、引数3000で例外を発生させる */
try {
account.deposit(1000);
account.withdraw(3000);
System.out.println("残高超過引数テスト失敗。例外発生できず");
}
catch (Exception e) {
System.out.println("残高超過引数テスト成功。例外:" + e.getMessage());
}


//getBlance()テスト
System.out.println("");
System.out.println("getBlance()テスト");
/** 残高1000円テスト 期待値1000円 */
account = new BankAccount(); //accountをリセット
double expectedAmount = 1000;
account.deposit(expectedAmount);
if (account.getBlance() == expectedAmount) {
System.out.println(expectedAmount + "円入金後テスト成功。Balance : " +
account.getBlance());
}
else {
System.out.println(expectedAmount + "円入金後テスト失敗。Expected Balance :" +
expectedAmount + " Actual Balance ; " + account.getBlance());
}

/** 残高399円テスト 期待値399円 */
account = new BankAccount(); //accountをリセット
expectedAmount = 399;
account.deposit(1000);
account.withdraw(601);

if (account.getBlance() == expectedAmount) {
System.out.println(expectedAmount + "円入金後テスト成功。Balance : " +
account.getBlance());
}
else {
System.out.println(expectedAmount + "円入金後テスト失敗。Expected Balance : " +
expectedAmount + " Actual Balance ; " + account.getBlance());
}

//getBalance()テスト
System.out.println("");
System.out.println("getBalance()テスト");
/** 残高1000円テスト 期待値1000円 */
account = new BankAccount(); //accountをリセット
expectedAmount = 1000;
account.deposit(expectedAmount);
if (account.getBalance() == expectedAmount) {
System.out.println(expectedAmount + "円入金後テスト成功。Balance : " +
account.getBalance());
}
else {
System.out.println(expectedAmount + "円入金後テスト失敗。Expected Balance :" +
expectedAmount + " Actual Balance ; " + account.getBalance());
}

/** 残高399円テスト 期待値399円 */
account = new BankAccount(); //accountをリセット
expectedAmount = 399;
account.deposit(1000);
account.withdraw(601);

if (account.getBalance() == expectedAmount) {
System.out.println(expectedAmount + "円入金後テスト成功。Balance : " +
account.getBalance());
}
else {
System.out.println(expectedAmount + "円入金後テスト失敗。Expected Balance : " +
expectedAmount + " Actual Balance ; " + account.getBalance());
}

}
}
━━━━━━━━━━━━ ここまで ━━━━━━━━━━━━━━━━━━

前回の宿題では、あなたは、getBlanceメソッド名のスペルがミスではないかと上司に相談し、getBalanceというメソッドを追加することに決めました。というのも、公に公表したため、getBlanceとgetBalanceの差はaがあるかないかの違いで、不利益を被る人も出てくるかもしれません。そのため、getBlance()も残し、getBalance()を新たにつけくわえ、それについても、テストするという内容でしたね。

設問1のBankAccount.javaで完成していなかったところは、withdraw()メソッドでした。

------------------------------------------------------------------------
public void withdraw(double amount) throws Exception {
if (amount <= 0) {
throw new Exception("入力した金額は0かマイナスです。amount: " +
amount);
}
if (balance < amount) {
throw new Exception("残高を超えています");
}
if (amount > 20000) {
throw new Exception("一度に引き落としできる額の上限は" +
20000 + "です");
}
this.balance -= amount;
}
------------------------------------------------------------------------

withdraw()メソッドに渡されるamountをプレコンディション(precondition,前提条件)でチェックし、条件を満たしていないときは、

this.balance -= amount;

を実行する前に、Exceptionをスローして、そこで、withdraw()メソッド内のプログラムの流れを終了させるというようにします。
最初は、引き出しにおいて、ゼロ(引き出しで0円というのは意味をなさない)とマイナス(マイナス円は引き出せない)という値は、不適切な値なので、Exceptionをスローします。あなたが、故意でスローしろ(命令形)とするのでthrowでしたね。一方、メソッド定義でメソッド(三人称単数)がスローするので、throws(s付き)と覚えました。

同じように、残高(balance)を引き出す分の額(amount)を上回った時と、一度に引き下ろせる額(20000)を上回ったときも、Exceptionをスローさせます。

そして、全ての前提条件をクリアーしたとき、はじめてthis.balance -= amountを実行するようにします。これを実行することによって、この(this)対象であるインスタンス(オブジェクト)のbalanceの値が実際amount分だけ目減りすることになります。たい焼きの例でいえば、あんこが少しだけ減ってしまうということですね。

BankAccountTest.javaでは、getBlance()メソッドとメソッド名以外は全く同じテスト文を付け加えています。withdraw()を使う側(呼ぶ側)では、BankAcountのwithdraw()で投げられたExceptionを、try/catch構文でキャッチしてあげます。

以上が宿題の解答でした。

ところで、withdraw()メソッドを使う側(呼ぶ側)は、必ず、try/catch構文で投げられたExceptionをキャッチしてあげないといけないのでしょうか?BankAccountExceptionTestで

■BankAccountExceptionTest.java
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━ ここから ━━━━━━━━━━━━━━━━━━
/**
* BankAccountのExceptionをテストするクラス
*
* @author Mr.Hack
*/
class BankAccountExceptionTest {

/**
* accountを1000円で初期化し、try/cathc構文なしで、
* 500円を引き出し。
*/
public static void main(String[] args) {

// accountインスタンスを1000円で初期化
BankAccount account = new BankAccount(1000);

//400円引き出し
account.withdraw(400);
}
}
━━━━━━━━━━━━ ここまで ━━━━━━━━━━━━━━━━━━

を実行するとどうなるでしょうか?withdraw()メソッドは、Exceptionをスローするのでしたね。BankAccountのAPIにもそう書いてあります。withdraw()メソッドを使う側(BankAccountクラスのクライアントという)はその投げられたExceptionを何らかの形でキャッチしてあげるかしてあげないといけませんね。そのため、上記のBankAccountExceptionTest.javaをコンパイルすると、

------------------------------------------------------------------------
BankAccountExceptionTest.java:19: 例外 java.lang.Exception は報告されません。スローするにはキャッチまたは、スロー宣言をしなければなりません。
account.withdraw(400);
^
エラー 1 個
------------------------------------------------------------------------

となり、コンパイルエラーとなります。これを解決するには、

おおもとのmain()メソッドが、throws(s付き)してあげるか

■BankAccountMainExceptionTest.java
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━ ここから ━━━━━━━━━━━━━━━━━━
/**
* BankAccountのExceptionをテストするクラス
*
* @author Mr.Hack
*/
class BankAccountMainExceptionTest {

/**
* accountを1000円で初期化し、try/cathc構文なしで、
* 500円を引き出し。main()でExceptonをスロー
*/
public static void main(String[] args) throws Exception {

// accountインスタンスを1000円で初期化
BankAccount account = new BankAccount(1000);

//400円引き出し
account.withdraw(400);
System.out.println("残高 : " + account.getBalance());
}
}
━━━━━━━━━━━━ ここまで ━━━━━━━━━━━━━━━━━━

または、withdraw()メソッドをtry/catch構文でくくってあげるかしないといけません。

■BankAccountTryCatchExceptionTest.java
━━━━━━━━━━━━ ここから ━━━━━━━━━━━━━━━━━━
/**
* BankAccountのExceptionをテストするクラス
*
* @author Mr.Hack
* @version 1.08115
*/
class BankAccountTryCatchExceptionTest {

/**
* accountを1000円で初期化し、try/cathc構文なしで、
* 400円を引き出し。main()でExceptonをスロー
*/

public static void main(String[] args) {

// accountインスタンスを1000円で初期化
BankAccount account = new BankAccount(1000);

//400円引き出し
try {
account.withdraw(400);
System.out.println("残高 : " + account.getBalance());
}
catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
━━━━━━━━━━━━ ここまで ━━━━━━━━━━━━━━━━━━

実は、先のBankAccountExceptionTest.javaでコンパイルエラーを出さない方法がもうひとつあるのです。それは、スローするExceptionをRuntimeExceptionに変えるのです。

■ランタイムException (Runtime Exception)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

BankAccount.javaのwithdraw()メソッドのスローされるExceptionをRuntimeExceptionにかえ、throwsのExceptionもRuntimeExceptionに変えて、今回のテストに必要なメソッドだけを書いたものがBankAccountRuntimeException.javaで、それに対応するテストクラスが、BankAccountRuntimeExceptionTest.javaです(先BankAccountExceptionTest.javaのBankAccountで初期化する変わりに、BankAccountRuntimeExceptionでaccountを初期化)。まずは、下記の二つのjavaファイルを別々に同じフォルダ内に保存し、CPadでBankAccountRuntimeExceptionTest.javaをコンパイル・実行してください。


■BankAccountRuntimeException.java
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━ ここから ━━━━━━━━━━━━━━━━━━
/**
* バンク預金口座クラス。顧客の口座の出し入れ、残高
* 照会をおこなう(通貨単位:円)。預入引き落とし時、
* Precondition(条件)をチェックし、条件に合わない場合は、
* 例外を発生させる。残高をゼロとするデフォルトのコンストラクタ、
* 預金額をセットできるコンストラクタがある。また、一度に引き出せる
* 上限は2万円してある。RuntimeException説明のためBankAccount.javaを
* 簡略化。
*
* @author Mr.Hack
*/
public class BankAccountRuntimeException {

/**
* 口座の残高
*/
private double balance;
/**
* amount分を残高としてセットするコンストラクタ。
* 初期化時(新しい口座作成時)、預金額を残高としてセットする。
*
* @param amount 口座に預け入れる金額(預金)
*/
public BankAccountRuntimeException(double amount) {
this.balance = amount;
}

/**
* amount分の金額を引き出す。amountが
* ゼロかマイナスの時、引き落とし金額が残高を上回った時、
* あるいは、一度に引き出せる上限金額を上回った時、例外発生。
*
* @param amount 引き出す金額
* @exception RuntimeException amountがゼロかマイナスの場合、
* 引き出し額が残高を上回った場合、
* 一度に引き出せる金額を上回った場合、
* 例外発生
*/
public void withdraw(double amount) throws RuntimeException {
if (amount <= 0) {
throw new RuntimeException("入力した金額は0かマイナスです。amount: " +
amount);
}
if (balance < amount) {
throw new RuntimeException("残高を超えています");
}
if (amount > 20000) {
throw new RuntimeException("一度に引き落としできる額の上限は" + 20000 +
"です");
}
this.balance -= amount;
}

/**
* 現在の残高を戻り値として返す。
*
* @return balance 口座にある現在の残高
*/
public double getBalance() {
return this.balance;
}
}
━━━━━━━━━━━━ ここまで ━━━━━━━━━━━━━━━━━━

どうですか?今度は、withdrawを使う側では、try/catch構文を使わなくても、main()メソッドでthrowsキーワードを使わなくてもコンパイルエラーにならなかったですね。


■RuntimeExceptionクラス
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Javaでエラー(Error)例外(Exception)の最上位に位置するスーパークラスがThrowableクラスだということを前回お話しました。そのサブクラスに、ErrorクラスとExceptionクラスがあります。Java SDKのAPIを見てみましょう(見方がわからない方はvol.003を参照)。Throwableのクラスを見ると、

────────────────────────────────────
直系の既知のサブクラス:
Error, Exception
────────────────────────────────────

とありますね。Errorクラスは、基本的にプログラマではどうにも扱えないクラスです。Errorクラスを継承しているクラスはtry/catch構文では、使えますが、意味がありません。というのも、Errorクラスがスローされるのは異常な状況だからです。とうてい、プログラマの手にはおえません。代表的なものにNoClassDefFoundErrorがありますね。このクラスはErrorクラスを継承しています。コンパイルの時には存在しているものが、何らかの原因で、実行時には存在しなくなっている場合にスローされます。これをtry/catch節やthrowsで宣言しても、到底プログラムをリカバリーすることができません。

試しに、NoClassDefFoundErrorをスローさせてみましょう。そのためには、まず拡張子がclassのファイルを消去(存在しないように)しておかないといけません。CPadでBankAccountRuntimeExceptionTestクラスのタグを選択します。メニューの『実行』→『エクスプローラーを起動』でエクスプローラーを起動するとBankAccountRuntimeExceptionTestがあるフォルダが開きます。そのフォルダの拡張子がclassを(もしあれば)、全て消去します。そして、CPadにもどり、BankAccountRuntimeExceptionTestのタグを選択してあることを確認し、『実行』→『実行』を選びます。コンパイルをしないで実行するので、拡張子がclassであるファイルがないまま、javaコマンドを実行することになります。当然、クラスファイルがないので、NoClassDefFoundErrorクラスがスローされます。これは、プログラマの責任外のことですね。ファイルが存在しないことは、プログラマが実行するときにミスがあったとしても、プログラマが書いたプログラム自体の責任ではないのです。

もう一つのExceptionクラスは以前説明しました。そのサブクラスに、RuntimeExceptionという特殊なクラスがあります。このクラスを継承しているクラスはとりわけ特殊です。というのも、RuntimeException以下のクラスは、キャッチされていなくても、コンパイル時には、エラーとならないのです。例を挙げれば、先ほどのBankAccountRuntimeExceptonクラスのwithdraw()メソッドはRuntimeExceptionをスローしますが、使う側で、try/catch構文または、main()メソッドでthrowsキーワードを使って宣言しなくても、エラーとならないのです。RuntimeExceptionクラスとそれ以下のサブクラス群はコンパイル時ではなく実行時(ランタイム)に『条件によって』エラーを出すのです。この『条件によって』がみそですね。逆に言えば、『条件によって』は、ランタイムにもエラーがでないのです。実際にwithdraw()メソッドを見てみましょう。

public void withdraw(double amount) throws RuntimeException {
if (amount <= 0) {
throw new RuntimeException("入力した金額は0かマイナスです");
}

this.balance -= amount;
}
}

withdraw()メソッドにはamountが渡されます。そのときに、amountがゼロより大きければ、RuntimeExceptionはスローされませんね。つまり、実行時にはRuntimeExceptionの例外は発生しないのです。amountがゼロ以下の時だけ、RuntimeExceptionの例外だけ発生するのです。amountがゼロ以下か、ゼロより大きいかは、コンパイル時では分かりません。実行時になってはじめて、withdrawに1000が渡されるのか、-1が渡されるのかが分かります。実行時に『ゼロ以下の場合』には、スローされるのが、RuntimeExceptionです。

なぜ、このようにコンパイル時ではなく実行時にスローするようになっているのでしょうか?これは、プログラマの責任と関係しています。RuntimeExceptionクラスまたは、そのサブクラスがスローされる場合は、プログラマが怠惰であったという警告でもあるのです。どういうことかと言いますと、withdraw()メソッドには、APIでamountがゼロかマイナスの時はRuntimeExcptionがスローされると書いてあるのです。これがルールです。つまり、withdraw()を使うときはゼロかマイナスを渡してはいけないのです。そのルールを守っていれば、例外を発生させませんよ、ということです。ですから、メソッド定義で、throwsキーワードをつかってRuntimeExceptionを宣言する必要もないのです。

// メソッド定義でthrows RuntimeExceptionの宣言は省略可
public void withdraw(double amount) {
if (amount <= 0) {
throw new RuntimeException("入力した金額は0かマイナスです");
}

this.balance -= amount;
}
}

一方で、BankAccountRuntimeExceptionのクライアントは、withdraw()メソッドを使うときに、

BankAccountRuntimeException account;
account = new BankAccountRuntimeException(1000);
// クライアント(プログラマ)はルールにしたがってマイナスではない値、
// 400を渡す
account.withdraw(400);

とできるのです。withdraw()メソッドに渡されるamountの値は、ゼロまたはマイナスでない値であると想定しているのです。それを守って入れさえすれば、例外も発生しないし、使う側では、try/catch構文を使う必要もないのです。
RuntimeExceptionでスローされる場合は、コンパイラーはちゃんとメソッドでthrows宣言をしているか、使う側のクライアント側ではtry/catch構文を使っているかはチェックしません。そのため、コンパイルエラーにはならないのです。

RuntimeExceptionを使えば、プログラムの記述が少なくなり、願ったりかなったりですね。しかしながら、いいことばかりではないのです。もし、使う側のクラスが、ユーザーからコマンドプロンプト上からの値をBankAccountRuntimeExceptonクラスのwithdraw()メソッドに渡した場合はどうでしょう。ユーザーはもしかすると、マイナスである-1000をコマンドプロンプトから入力するかもしれません。そのときは、withdrawを使うクライアントが、ゼロまたはマイナスでない値というルールを破って-1000を渡すことになるので、withdraw()メソッドはRuntimeExceptionをスローします。そのとき、クライアント側では、try/catch構文も用意しておらず、かつmain()メソッドでもthrowsキーワードも用意していません。その場合、Javaインタープリタがキャッチしてくれます。


後編で、実際にRuntimeExceptionを見てみましょう。引き続き、後編をお楽しみ下さい。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
◆Javaで珈琲ブレイク◆
────────────────────────────────────
皆様からの激励・批判のメールをお待ちしております。
【発行者】 Mr.Hack - javacafebreak@hotmail.com
【掲示板】 http://fweb.midi.co.jp/~romanhikou/cafe_entrance.html
※質問は上記の掲示板からどうぞ。
【サイト】 http://mrhack.hoops.ne.jp/
【発行数】 まぐまぐ[853] Melma[130]
【解除】http://mrhack.hoops.ne.jp/
※解除は上記のサイトからいつでもできます。
────────────────────────────────────
(c)2002 MR.HACK ALL RIGHTS RESERVED
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

© 2002 MR.HACK ALL RIGHTS RESERVED