7.1エラー処理
エラーは、Javaプログラムが実行されていることを前提と発生しました。エラーは、エラーメッセージ、または不安定なネットワーク接続を含むファイルによって引き起こされることが(私たちは言及したくない)無効な配列のインデックスまたはオブジェクトが原因となったオブジェクトへの参照を割り当てられていません。ユーザーは、エラーが発生したときにプログラムが敏感に実行したいです。操作はエラーのため完了できない場合、プログラムはすべき
- 安全な状態に戻り、ユーザーが他のコマンドを実行することができます。または
- これは、ユーザーがすべての作業を保存して、優雅にプログラムを終了させることができます。
データを安全な状態にロールバックすることができたり、ユーザーの作業を保存して喜んでコードを終了することから検出(あるいは鉛)、エラー状態コードが離れて通常であるので、行うのは簡単ではないかもしれません。タスク例外処理は、エラーがエラーハンドラに発生した場所からの制御の転送は、この状況に対処することができます。例外をハンドラに、それが発生する可能性があり、アカウントのエラーや問題を考慮する必要があります。あなたは考慮する必要がありますどのような問題?
- ユーザーの入力エラー。避けられないタイプミスに加えて、一部のユーザーは、自分の道を開くのではなく指示に従うのが好き。例えば、ユーザは、構文エラーのURLへの接続を要求すると仮定します。あなたのコードは文法をチェックし、それはチェックしませんと仮定しなければなりません。そして、ネットワーク層は文句を言います。
- デバイスエラー。ハードウェアは、常にあなたの要件に応じて動作しません。プリンタがオフにすることができます。Webページが一時的に利用できないかもしれません。機器の故障は通常、タスクの実行中に発生します。例えば、印刷時のプリンタは、用紙切れの可能性があります。
- 物理的な制限。ディスクが埋めることができ、利用可能なメモリの不足を。
*
コードのエラー。メソッドは正しく実行されないことがあります。例えば、それは間違った答え、または他の方法の誤った使用を与える可能性があります。無効な配列インデックスの計算は、存在しないか、空のスタックは、ハッシュテーブル内の符号誤りの一例であるポップしようとしないエントリを見つけることを試みます。
応答エラーの伝統的な方法は、エラーコードを解析するための特別な方法の呼び出し元に返されます。例えば、情報は一般的に、ファイルの復帰方法から読み込まれる-1
代わりに標準文字で、ファイルマーカー値の最後。これは異常な状態の数に対処する効果的な方法です。他の一般的なエラー条件は、戻り値があることを示すnull
参照。
残念ながら、常にエラーコードを返しません。これは、有効と無効なデータを区別する明白な方法はないかもしれません。この方法は、単純に返されない整数を返し-1
、エラーを示すために、値は、-1
完全に有効な結果であってもよいです。
我々は、第5章で述べたように代わりに、Javaはそれがそのタスクを完了するために、通常の方法ではない場合、各メソッドは、代替出口経路であることができます。この場合、メソッドは値を返しません。代わりに、エラーメッセージをカプセル化するオブジェクトをスローされます。このメソッドはすぐに終了していることに注意してください。それは、通常の(または任意の)値に戻りません。また、コードが実行する方法の呼び出し時に再開されません。逆に、例外処理メカニズムは、検索例外ハンドラは、この特定のエラー条件を処理することができます開始します。
異常は独自の文法を持ち、特殊な継承階層の一部です。私たちは、最初の文法を学び、その後、効果的に、この言語機能を使用する方法についていくつかのヒントを与えるだろう。
7.1.1珍しい分類
Javaプログラミング言語では、例外オブジェクトは常にThrowable
クラスから派生したインスタンス。あなたはすぐに見るように、あなたのニーズに合わせていないJava例外クラスに組み込まれている場合、あなたは独自の例外クラスを作成することができます。
図7.1は、Javaの略図例外階層です。
7.1 Javaの例外階層図
すべての例外がされていることに注意してくださいThrowable
:継承されたが、階層がすぐに2つのブランチに分割Error
してException
。
Error
階層は、Javaランタイムシステムの内部エラーおよびリソースの枯渇を説明します。このタイプのオブジェクトをスローするべきではありません。このような内部エラーした場合、ユーザーに通知し、除きますほとんど無力、正常外のプログラムを終了させようとします。これらのケースは非常に稀です。
Javaプログラミング時には、注意してException
階層を。Exception
階層は、2本の枝に分かれています。RuntimeException
例外が派生していない例外を派生します。一般的なルールは次のとおりです。RuntimeException
プログラミングエラーが発生したため、異常が発生します。その他の例外は、そのようなI / Oエラーが元の良いプログラムで発生すると、理由は悪いことで発生します。
継承されます。RuntimeException
これらの問題を含めて例外
- 悪いキャスト
- クロスボーダー配列アクセス
- nullポインタアクセス
ないからRuntimeException
含めて継承された異常、
- ファイルの内容の末尾を越えて読み取ろうとします
- 私は存在しないファイルを開こうとします
- 既存のクラスを表す文字列を見つけることを試みてはいけない
Class
オブジェクトを
「それはだ場合はRuntimeException
ルールがうまく機能し、それはあなたの責任です」。回避によるアレイ境界配列インデックスによってテストArrayIndexOutOfBoundsException
。変数が発生していない変数を使用する前に、空であるかどうかをチェックする場合NullPointerException
。
どのように存在しないファイルについてはどうですか?あなたは、ファイルが存在するかどうかを確認し、とにかくそれを開くことができませんか?さて、ファイルが存在するかどうかを確認した後に、それはすぐに除去することができます。そのため、「存在」の概念がないだけで、コードの上に、環境に依存します。
Java言語仕様は、いずれからも呼び出しをError
チェックしません異常またはクラスRuntimeException
の異常にわたり継承されたクラスを。他のすべての例外はチェック例外と呼ばれています。これは、我々が採用している便利な用語です。あなたはすべてのために例外ハンドラを提供し、コンパイラのチェックが例外をチェックしました。
注意を払います
RuntimeException
名前は少し紛らわしいです。もちろん、我々が議論してきたすべてのエラーは、実行時に発生しました。
C ++注意
あなたは、標準C ++ライブラリ(より限定された)例外階層に精通している場合は、この時点で、あなたは混同されることがあります。2つがあり、基本的なC ++の例外クラスは次のとおり
runtime_error
とlogic_error
。logic_error
Javaのクラスの行為RuntimeException
、また、プログラム内の論理エラーを表します。runtime_error
クラスは、予測不可能な問題によって引き起こされた例外の基底クラスです。それは属していないのJavaと同等であるRuntimeException
例外のものを型に。
7.1.2文の異常
それは状況が処理できない遭遇した場合、Javaメソッドが例外をスローすることができます。発想は単純です:だけでなく、それが返すどのような値Javaコンパイラを指示する方法は、それはまた、何が悪かったのか、コンパイラに指示します。例えば、ファイルのコードから読み取るしようとしているが、ファイルが存在しないか、または空であることを知っています。したがって、コードは、それがのIOExceptionのいくつかの種類を投げることができるコンパイラに通知するために必要なファイル情報を処理しようとします。
ヘッドは、メソッドがチェック例外をスローすることができます反映するために変更されます。あなたはあなたの方法は、第一の方法である場所で例外をスロー公開することができます。例えば、コンストラクタFileInputStreamの標準ライブラリクラスのステートメントがあります。(入力と出力の詳細については、第1章、第II巻を参照。)
public FileInputStream(String name) throws FileNotFoundException
ステートメントは、このコンストラクタからと言っString
パラメータ作成しFileInputStream
たオブジェクトを、それはまたによって引き起こされる可能性がFileNotFoundException
特定の方法でエラーが発生しました。これは悪い状態が起こる必要がある場合は、コンストラクタの呼び出しは、新しい初期化されませんFileInputStream
オブジェクトを、しかし、スローFileNotFoundException
オブジェクトクラスを。その場合は、ランタイムシステムが処理する方法を知って検索を開始しますFileNotFoundException
例外ハンドラオブジェクトを。
あなたがあなた自身の方法を書くとき、あなたは、実際のメソッドがスローされる可能性があります破棄される各オブジェクトを公開する必要はありません。あなたはの方法書かなければならないことを理解するにはthrows
時間を広告(およびコンテンツ)句を、次の4つの条件でどのような場合には例外がスローされますに注意してください:
- あなたは、次のようなテスト異常、トリガするメソッドを呼び出す
FileInputStream
コンストラクタを。 - あなたは、エラーを検出し、使用
throw
ステートメントは、(我々は次のセクションで紹介しますチェック例外をスローthrow
文)。 - あなたは、(この場合は故障の原因となった異常などのプログラムエラーを生成することができる
ArrayIndexOutofBoundsException
[-1] = 0です)。 - 内部エラーが発生したライブラリ内または仮想マシンが実行されています。
どちらかが最初の2つのシナリオで発生した場合、あなたはあなたのプログラマは珍しい方法の可能性を使用します伝える必要があります。なぜ?任意の方法は、例外は潜在的な死のトラップでスローされます。あなたは例外ハンドラをキャッチしない場合は、現在の実行スレッドが終了します。
そして、クラスの一部として提供され、Javaメソッドの宣言は、法であなたの頭を投げると、例外仕様を使用します。
class MyAnimation
{
. . .
public Image loadImage(String s) throws IOException
{
. . .
}
}
この方法は、例外の選択された複数種類のにつながる可能性がある場合、例外は、ヘッダ内のすべてのクラスを一覧表示しなければなりません。カンマ、以下の例で区切ります:
class MyAnimation
{
. . .
public Image loadImage(String s) throws FileNotFoundException, EO
{
. . .
}
}
しかし、それから、つまり、内部のJavaエラーを宣伝する必要はありませんError
継承された異常。これらの例外をスローすることが任意のコードが、彼らは完全にあなたのコントロールを超えています。
同様に、発表はから継承すべきではないRuntimeException
未確認の例外。
class MyAnimation
{
. . .
void drawImage(int i) throws ArrayIndexOutOfBoundsException // ba
{
. . .
}
}
あなたが完全に制御を持っているこれらの実行時エラー。あなたは、配列のインデックスエラーについてとても心配している場合、それはそれらを修正するのではなく、彼らが発生する可能性を促進するための時間を取る必要があります。
要約すると、この方法は、それがすべてのチェック例外を投げることができることを宣言しなければなりません。あなたのコントロールを超えた未確認の例外が(Error
)、または初期条件によって許可されていない(RuntimeException
)が発生。方法は正直にすべての異常な検査を宣言するために失敗した場合、コンパイラはエラーメッセージを発行します。
もちろん、あなたはかなり珍しいの文よりも、例外をキャッチすることができて、あなたが多くの例で見ることができるように。だから、それはプロセスからの例外をスローしません、仕様をスローする必要はありません。あなたは、この章の後半で表示されます例外をキャッチし、または他の誰かが例外をキャッチできるようにする方法を決定することです。
注意深く
スーパーオーバーライドメソッド場合、サブクラスのメソッドの宣言を確認し、より一般的な異常のスーパークラスのメソッドよりも例外を宣言することはできません。(あなたはどんな例外サブクラス方法をスローしないことがあり、より具体的な例外をスローすることができます。)特に、スーパークラスのメソッドがチェック例外をスローしなかった場合、サブクラスはできません。あなたが上書きしている場合たとえば、
JComponent.paintComponent
、その後、paintComponent
スーパークラスのメソッドが例外をスローしませんので、この方法は、任意のチェック例外をスローすることはできません。
メソッドは、クラスは、それが特定のクラスに属する例外インスタンスをスローすることを宣言する場合と、それは例外またはクラスのクラスのいずれかを投げることができます。例えば、FileInputStream
コンストラクタは、それがきっかけ宣言することができますIOException
。この場合、あなたはそれがどのタイプか分からないことがありIOException
、それは通常であってもよいIOException
、また、(例えば、サブカテゴリの多様とすることができるFileNotFoundException
オブジェクトのうちの1つ)。
C ++注意
throws
Cでの指定子は++throw
が、1つの重要な違いで、同じ指定子を。C ++では、実行時の執行でthrow
指定ではなく、コンパイル時に。言い換えれば、C ++コンパイラが懸念例外仕様をしません。1はに属していない場合は、throw
例外機能の一覧を投げる、あなたが呼び出すunexpected
機能を、デフォルトで、プログラムは終了します。また、C ++には、与えられていない場合は
throw
仕様を、関数が任意の例外をスローすることがあります。Javaでは、何もありませんthrows
すべてのチェック例外をスローしない可能性があります方法として説明が。
例外をスローする方法7.1.3
さて、それは恐ろしいことあなたのコードだったと仮定します。あなたはこの方法持っているreadData
ファイルを読み込み、ファイルヘッダのコミットメントを
Content-length: 1024
しかし、あなたは733個の文字の後に、ファイルの末尾を取得します。あなたは例外をスローすることを、これは非常に珍しいと思うかもしれません。
あなたは、スローされた例外の種類を決定する必要があります。いくつかはIOException
良い選択です。JavaのAPIドキュメントを使用している場合、あなたは見つけるでしょうEOFExchange
、その説明は「偶然プロセスにおけるEOF信号入力に達する。」であります ここでは、スロー方法は次のとおりです。
throw new EOFException();
それとも、あなたが選択することができます
var e = new EOFException();
throw e;
以下では、これらのすべての要素を組み合わせたものです:
String readData(Scanner in) throws EOFException
{
. . .
while (. . .)
{
if (!in.hasNext()) // EOF encountered
{
if (n < len)
throw new EOFException();
}
. . .
}
return s;
}
EOFException
第二は、文字列引数のコンストラクタを受け入れます。あなたは、より密接に、より良いこれを利用するためには、異常な状況を記述することができます。
String gripe = "Content-length: " + len + ", Received: " + n;
throw new EOFException(gripe);
あなたが見ることができるように、あなたのための既存の例外クラスの有効ならば、例外をスローすることは容易です。この場合には:
- 適切な例外クラスを検索します。
- そのクラスのオブジェクトを構築します。
- それを投げます
メソッドが例外をスローしたら、それは呼び出し元に戻りません。これは偽造デフォルトの戻り値またはエラーコードを心配する必要がないことを意味します。
C ++注意
C ++とJavaでスローされ、わずかな違いと同じです。Javaでは、あなただけのスローすることができ
Throwable
、サブクラスオブジェクトを。C ++では、あなたは、任意の型の値を投げることができます。
7.1.4作成例外クラス
標準の例外クラスで問題が発生することがありますあなたのコードが適切に記述されていません。この場合、あなた自身の例外クラスを作成することは容易です。のみからException
またはからException
サブクラス(例えば、IOException
それが誘導されます)。通常は、デフォルトコンストラクタと詳細なメッセージを含むコンストラクタを与えられました。(Throwable
スーパークラスのtoString
メソッドは、デバッグのために非常に便利であり、詳細なメッセージを含む文字列を返します。)
class FileFormatException extends IOException
{
public FileFormatException() {}
public FileFormatException(String gripe)
{
super(gripe);
}
}
今、あなたはあなたの独自の例外タイプをスローする準備が整いました。
String readData(BufferedReader in) throws FileFormatException
{
. . .
while (. . .)
{
if (ch == -1) // EOF encountered
{
if (n < len)
throw new FileFormatException();
}
. . .
}
return s;
}
java.lang.Throwable
1.0
Throwable()
メッセージの詳細な構成ないThrowable
オブジェクト。Throwable(String message)
指定された新しいメッセージの詳細な構成Throwable
オブジェクト。慣例により、派生したすべての例外クラスは、詳細メッセージを持つデフォルトコンストラクタコンストラクタをサポートしています。String getMessage()
取得Throwable
詳細なメッセージオブジェクトを。