Javaの基本ノート-7-例外、アサーションとロギング
理想的な世界では、ユーザの入力形式のデータは常に正しいです、また、存在しなければならないファイルを開くことを選択し、バグを表示されません。これまでのところ、この本は、私たちは、このようなコードであるに理想的なレルムを思わ発表しました。現実の世界で問題に不正なデータやコードの完全であるしかし、我々は今、これらの問題肥沃な時間に対処するには、Javaプログラミング言語のメカニズムを議論しています。
エラーが発生したときに人々が不快に感じます。プログラムやユーザデータの損失による、いくつかの外部環境のエラーによる動作中のユーザプログラム、場合、ユーザーは、もはやそのようなことが発生するのを避けるために、このプログラムを使用する必要がないこと、または少なくとも次の操作を行う必要があります:
- ユーザーにエラーに注目してください。
- すべての作業結果を保存します。
- これは、ユーザーが適切な形でプログラムを終了することができます。
例外については、例えば、誤入力プログラムのクラッシュにつながることがあり、Javaは(例外処理)をエラー処理例外と呼ばれる技術を使用して対処するためのメカニズムを取り込みます。C ++やDelphiの例外処理で扱うJava例外は非常に似ています。この章のパート1は、第1のJavaの例外を導入しました。
試験中、多くのテストの必要性は、プログラム動作の正しさを検証します。しかし、これらのテストは非常に時間がかかる可能性がテストが完了した後、それらを維持していない。したがって、これらのテストは削除することができ、他のテストは、それらをバック&ペーストする必要がある場合、これは非常に面倒なものです。この章の第2部では、選択的検出を可能にするためにアサーションを使用する方法について説明します。
プログラムエラーが発生した場合、常にユーザまたは端末と通信することができません。この時点で、あなたは、後で分析するために、下に発生する問題を記録することを望むかもしれません。この章の第3部では、標準のJavaロギング・フレームワークについて説明します。
1つの処理エラー
エラーは、実行するJavaプログラム中に発生したと仮定します。このエラーは、エラー・メッセージを含むファイルであってよい、またはネットワーク接続の問題が発生するだけでなく、無効な配列のインデックス、または参照オブジェクトが生じ割り当てられていない使用しようとすることができます。ユーザーは、エラーが発生した場合、プログラムはいくつかの不合理な行動を使用することができます期待しています。エラーのために特定の操作が完了していないようならば、プログラムはすべき:
- 安全な状態に戻り、ユーザーが他のいくつかのコマンドを実行することができます。または
- これにより、ユーザーはすべての操作の結果を保存することができますし、プログラムを終了する適切な方法
これを行うには簡単なことではありません。この理由は、エラー状態コードは、通常、はるかに安全な状態にデータを許可、またはユーザーの結果を保存することができ、通常はプログラムを終了するコードから削除され検出することである(またはスロー)。例外処理タスクは、エラーがこの状況を扱うことができるエラープロセッサに発生した場所から制御を転送することです。あなたのプログラムで例外を処理することができるようにするためには、プログラムがエラーや問題だけでなく、注意を必要とする問題の種類を表示されることがあり勉強しなければなりません。
ユーザーの入力エラー
必然的なキーボードの入力エラーに加えて、一部のユーザーは、プログラムの要件に準拠していない、独自の方法を好みます。例えば、ユーザは、接続URLを要求し、構文が正しくないと仮定します。チェックされていない、それがネットワーク層を警告する場合は、このプログラム・コードでは、チェックする必要があります。
デバイスエラー
ハードウェアは、常にそれが何をすることはありませんし、それが何をしますか。プリンタがオフにすることができます。Webページが一時的に閲覧することができないことがあります。プロセスタスクでは、ハードウェアの問題がしばしば発生します。例えば、印刷時のプリンタが紙ではないかもしれません。
物理的制約
ディスクがいっぱいで、使用可能なストレージ容量は、最大使用されてきました。
コードエラー
の手続き方法が正しく実行されないことがあります。例えば、この方法は間違った答えを返すか、誤って他のメソッドを呼び出すことができます。配列インデックスの計算では、これらは、コードエラーで、ハッシュテーブルに存在しないレコードを検索しようとしている、または実行するために、空のポップ操作を見つけようとし、正当ではありません。
間違った方法では、伝統的なアプローチは、呼び出し元のメソッドによって特別なエラーコードの分析を返すことです。例えば、ファイルから情報を読み取るための方法は、戻り値は、通常、標準的な文字が、ファイルの終わりを示す-1ではありません。多くの異常な状態のため、このアプローチが可能です。一般的な条件はエラーの戻り値がnull参照であることを示しているもあります。
残念ながら、すべてではないが、いずれの場合にエラーコードを返すことができます。明示的に有効なデータと無効なデータの間に区別しない場合があります。-1は完全に合法的な結果である可能性が高いので、整数への一つの方法は、単純に、-1を返すことでエラーを返すことができません。5章で説明したように、この方法は、通常のチャネルを使用できない場合、Javaで、上述したように、そのタスクを完了し、別のパス方法を終了することができます。この場合、本方法は、任意の値を返さないが、ターゲットエラーメッセージをカプセル化する(スロー)スロー。この方法はすぐに出口が任意の値を返さないことに注意してください。また、このメソッドを呼び出すコードを継続することができなくなり、代わりに、例外処理メカニズムは、この異常な状況(例外ハンドラ)を扱うことができる例外ハンドラを検索し始めました。異常は独自の文法と、特定の継承構造を有しています。まず、効果的な言語機能を使用するためにスキルを与えられ、その後、次の構文を教えて、と。
1.1故障の分類
Javaプログラミング言語では、例外オブジェクトは、Throwableの派生クラスのインスタンスです。また、Javaの組み込み例外クラスは、需要を満たすことができない場合は、ユーザーが独自の例外クラスを作成することができ、後から見ることができます。
7-1は、Javaの例外階層の概略図です。
Throwable
Error Expception
IOException RuntimeException
すべての例外はThrowableのから継承されていることに留意すべきであるが、次の層は、すぐに2つのブランチに分け:エラーと例外
エラークラス階層は、内部エラーや資源枯渇のJavaランタイム・システム・エラーを示しています。アプリケーションは、オブジェクトのこのタイプを投げるべきではありません。加えて、このような内部エラーが、ユーザーへの通知、およびプログラムが安全に外に終了させるためにしようとする場合は、彼がこれ以上やることができませんでした。これはめったにケースではありません。
Javaプログラムの設計では、我々は例外階層を集中する必要があります。この階層構造と二股に分かれて:のRuntimeExceptionから派生した分岐、他の枝は例外が含まれています。プログラムエラーのRuntimeException属する異常を引き起こし、そしてプログラム自体には問題はないが、I / Oエラーが異常に起因するようなので、そのような問題は他の異常に属する:規則は、2つのブランチに分けられます:
RuntimeExceptionの例外から派生し、次のような状況が含まれます。
- エラー型変換。
- 範囲外の配列へのアクセス
- nullポインタアクセス
RuntimeException例外に由来するものではない、次のとおりです。
- ファイルのバックエンドでデータを読み取るしようとしています。
- 私は存在しないファイルを開こうとします。
- 与えられた文字列に応じたクラスのオブジェクトを検索しようとすると、このクラスの文字列表現は存在しません。
「異常のRuntimeExceptionは、それはあなたの問題でなければならない場合は、」かなり合理的なルールです。変数を使用する前にNullPointerExceptionの発生を防止するためにヌルであるかどうかを検出することによって、異常なArraylndexOutOfBoundsExceptionを回避する範囲外の配列インデックスにより検出されなければなりません。
どのように対処するファイルと、まだ存在していませんか?ファイルが存在するかどうかを確認して、とにかくそれを開けないのですか?あ、その前にこのファイルは、あなたの中にそこに削除されていたかどうかを確認することが可能です。したがって、「の存在は、」環境に応じて、だけでなく、あなたのコードに依存します。
Java言語仕様に生まれる非未チェック(チェック)の例外、チェック(チェック)例外によって呼び出された他のすべての異常と呼ばれるすべての例外ののRuntimeExceptionエラーまたは複数のクラスを送信します。これらは2つの非常に便利な用語です、後で使用されます。コンパイラは、例外が調査中で、すべての例外ハンドラのために提供するかどうかをチェックします。
1.2ステートメントは、例外をチェックします
あなたは状況が処理できない発生した場合は、Javaメソッドが例外をスローすることができます。理由は簡単です:メソッドが返されますどのような値をコンパイラに指示する必要がありますが、また、コンパイラに指示するだけでなく、何が悪かったのかと思われます。例えば、ファイルを読み取ることができる知っているファイルを読み込むためのコードの一部は、そのため、コンパイラは例外のIOExceptionクラスを投げることが通知するために必要なコードのファイル情報を扱うしようとすると、存在しないか空です。
その方法の最初の部分でスローされるすべての可能性のある例外を宣言する必要があります。これは、この方法の種類からスローされるヘッダチェック例外を反映しています。たとえば、次の文は、標準ライブラリで提供されるクラスのコンストラクタFilelnputStreamである(入力と出力のボリュームの詳細については、第2章Ⅱを参照してください。)
public FilelnputStream(String name) throws FileNotFoundException
この文は、コンストラクタは、指定されたパラメータに基づいてFilelnputStream Stringオブジェクトが生成されますが、また、FileNotFoundExceptionを例外をスローする可能性があることを示しています。この悪いが発生した場合、コンストラクタは、新しいのFileInputStreamオブジェクトを初期化しますが、FileNotFoundExceptionをクラスのオブジェクトをスローしません。この方法は実際に例外オブジェクトを投げている場合、システムはFileNotFoundExceptionを対象に対処する方法を知るために、例外ハンドラの実行のために検索を開始します。
すべての可能な例外をスローすることなく、独自のメソッドを書くときに宣言されています。この方法により、必要な場合については、例外をスローする必要があり、以下の4例顔に心に留めておく必要があり、例外がthrows節で宣言されなければならないかを指定例外条項がスローされます。
- 1)例えば、FilelnputStreamコンストラクタによってそのスロー例外をチェックするための呼び出しを。
- 2)プログラムがチェック例外がスローエラーが検出された実行している、とthrowステートメントを使用している(次のセクション)は、throw文を詳細に説明します。
- 3)エラーが処置、例えば、[-1] = 0このような非例外をチェックArraylndexOutOffloundsExceptionをスローしますが発生します。
- 4)Java仮想マシンとランタイムライブラリ内部エラーが表示されます。
最初の2つの状況のいずれかの場合は、例外をスローすることがあり、このメソッドを呼び出すプログラマを伝える必要があります。なぜ?いずれかのメソッドが例外をスローするので、死の罠である可能性が高いです。プロセッサは、この例外をキャッチしていない場合は、現在実行中のスレッドが終了します。
これらのJavaメソッドは、他の人が使用することができるため、例外仕様(例外仕様)に基づいている必要があり、このステートメントの方法の最初の部分に例外をスローします。
class MyAnimation {
...
public Image loadlmage(String s) throws IOException {
...
}
}
この方法は、より多くのチェック例外タイプをスローする場合に、あなたは、ヘッダーメソッド内のすべての例外クラスをリストする必要があります。各例外クラス間のカンマで区切られています。次の例に示すように:
class MyAnimation {
...
public Image loadlmage(String s) throws FileNotFoundException,EOFException
{
...
}
}
しかし、Javaはエラーエラーから継承された内部エラーを宣言する必要はありません。これらの例外をスローする可能性を秘めている任意のプログラムコードは、我々はそれをコントロールするいずれかの能力を持っていません。
同様に、例外をチェックするべきではありませんされていないステートメントは、RuntimeExceptionを継承します
class MyAnimation {
...
void drawlmage(int i) throws ArraylndexOutOfBoundsException // bad style
{
...
}
}
完全に私たちのコントロールの下でこれらのランタイムエラー。特に懸念の配列インデックスエラーがトリガされた場合、それはむしろ、これらのエラーの可能性の指示よりも、プログラムのエラーを修正するに費やした多くの時間でなければなりません。
要約すると、この方法は、すべての可能な宣言しなければなりません(エラー)を制御することはできませんいずれかのチェック例外の対象ではなく、チェック例外をスローし、または(のRuntimeExceptionを)避けるべきです。この方法は、すべてのチェック例外を宣言していない場合、コンパイラが発生する可能性があり、エラー・メッセージを発行します。
もちろん、私たちが知ることができ、前の例から:ほかに例外を宣言するために、また、例外をキャプチャすることができます。それは異常とされるよりも仕様をスローする必要がないメソッドにスローされません。その後、我々は例外がキャッチされ、または処理のために他のプロセッサによってスローされた方法を決定するについて説明します。
警告:あなたはサブクラスでスーパークラスをオーバーライドする場合は、文の中で宣言されたサブクラスの異常より一般的な方法は、(スーパークラスのメソッドよりも、例外を確認することはできませんが、それはあり、サブクラスのメソッドは、より具体的な投げることができます特に、例外を)投げる異常な、そうでないかは、スーパークラスのメソッドがすべてのチェック例外をスローしない場合は、サブクラスが任意のチェック例外を投げることができないことに留意すべきです。カスタムpaintComponentは、いずれかの例外を確認投げることができないので、例えば、カバレッジJComponent.paintComponent方法ならば、スーパークラスは、このメソッドは、例外をスローしません。
メソッド宣言クラスの例外は、例外をスローし、この例外は、特定のクラスのインスタンスである場合、このメソッドは、このクラスの例外、またはサブクラスの任意のクラスをスローすることが可能です。例えば、FilelnputStreamコンストラクタ文はIOExcetionが例外をスローすることがありますが、IOExceptionが異常の種類を特に知りませんでした。それは異常のサブクラスであってもよい、IOExceptionをすることができ、例えば、にFileNotFoundException
例外をスローする方法1.3
プログラムコード内で起こったいくつかの非常に悪いことを前提としています。readDataと呼ばれる方法は、以下の情報を含むヘッダ・ファイルを読み取っています。
Content-length: 1024
しかし、733文字のファイルをオーバー読んだ後。私たちは、例外をスローすることを望んで、これは異常な状況だと思います。
あなたは最初にスローされなければならない例外の種類を決定する必要があります。IOExceptionが異常は良い選択に起因します。慎重に見つけるのJava APIのドキュメント読んだ後:例外のEOFExceptionの記述がある「入力プロセスでの予期しないEOFの信号に遭遇しました」。これは、私たちが投げたいものです。以下の文は、この例外をスローです。
throw new EOFException();
若しくは
EOFException 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);
以前に見たことがあり、既存の例外クラスのために、この場合には、投げることは非常に簡単です:
- 1)適切な例外クラスを見つけます。
- 2)このクラスのオブジェクトを作成します。
- 3)オブジェクトがスローされました。
メソッドが例外をスローすると、このメソッドは、呼び出し元に戻すことはできません。言い換えれば、あなたは、返されるデフォルトまたはエラーコードを心配する必要はありません。
1.4例外クラスを作成します
プログラムでは、標準の例外クラスのいずれかが適切に問題を明確に記述することができないことがあります。この場合、独自の例外クラスを作成することは論理的なものです。私たちは、Exceptionから派生したクラスまたは例外サブクラスから派生したクラスを定義で行う必要があります。例えば、クラスの定義は、IOExceptionが由来します。伝統的に、クラス定義は2つのコンストラクタ、デフォルトコンストラクタが含まれている必要があり、他方が、細部を印刷します情報(スーパークラスの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 FileFornatException();
}
...
}
return s;
}
Throwable(); //构造一个新的Throwabie对象,这个对象没有详细的描述信息。
Throwable(String message); //构造一个新的throwabie对象,这个对象带有特定的详细描述信息。习惯上,所有派生的异常类都支持一个默认的构造器和一个带有详细描述信息的构造器。
String getMessage(); //获得Throwabie对象的详细描述信息
2例外をキャッチ
これまでのところ、すでに例外をスローする方法を知っています。このプロセスは非常に簡単です。ただ、それが理由段投げないでください。もちろん、いくつかのコードは、例外をキャッチする必要があります。キャッチ例外は慎重な計画が必要です。これは、次のセクションの内容が導入されます。
2.1例外をキャッチ
例外はどこにも捉えていないが発生した場合、そのプログラムが実行を終了し、コンテンツタイプとスタック例外を含むコンソール上の異常なメッセージを、プリントアウトされます。グラフィカル・インターフェース・プログラム(アプレットおよびアプリケーション)の場合は、例外をキャッチした後、それは情報のヒープ占をプリントアウトしますが、プログラムのデバッグ時のプログラムは、ユーザーインターフェイス(GUIの処理サイクルに戻ります、目に見えるコンソールウィンドウの最良の保証それは)最小化されていません。
例外をキャッチするには、try / catchブロックを設定する必要があります。次のように最も簡単なのは、ブロックを試してください。
try
{
code
more code
more code
}
catch (ExceptionType e)
{
handlerfor this type
}
tryブロック内のコードは、その後、catch節で説明した例外クラスをスローした場合
- 1)プログラムは、tryブロック内のコードの残りの部分をスキップします。
- 2)プログラム実行処理コードcatch節。
例外がスローされることなく、tryブロック内のコードと、プログラムはcatch節をスキップします。
任意のコード方式は、catch節で宣言されていない例外型をスローした場合、このメソッドはすぐに(異常に設計catch節のこのタイプの発信者を願っています)終了します。
例外キャプチャプロセスを実証するために、データを読み取る一般的なプログラムコードの下に与えられます:
public void read(String filename)
{
try
{
InputStream in = new FileInputStream(filename);
int b;
while ((b = in.read()3 != -1 )
{
process input
}
}
catch (IOException exception)
{
exception.printStackTrace();
}
}
なお、コードのほとんどが理解することは非常に簡単である文を試してみてください:読み込まれたバイトとプロセスをファイルの最後には、これまでに遭遇したまで。などのJava APIで見られるように、読みの方法は、IOExceptionをスローします。この場合、whileループのうち、全体の、catch句に、およびスタックトレースを生成します。一般的な手順については、実質的に正当化例外をこのように処理しました。他のオプションがありますか?
一般的には、最良のオプションは何もしませんが、呼び出し側に例外を渡すことです。readメソッドエラーならば、心配する必要は呼び出し側がメソッドを読んでみましょう!このアプローチを使用すると、このメソッドはIOExceptionをスローも宣言する必要があります。
public void read(String filename) throws IOException
{
inputStream in = new FileinputStream(filename);
int b;
while ((b = in.readO) != -1 )
{
process input
}
}
厳密に施行コンパイラが指定子をスローし、覚えておいてください。メソッドがスローする場合にチェック例外が呼び出され、それを処理し、またはパスを継続する必要があります。
どちらの方法が良いですか?一般的に、あなたは例外を処理する方法を知っている人をキャプチャする必要があり、そしてそれらの例外を続行する転送を処理する方法がわかりません。
あなたは例外を渡したい場合は、メソッドの呼び出し元に通知するメソッドを追加するヘッダに指定子をスローしなければならない例外をスローする可能性があります。
慎重に各メソッドが例外をスローして、自分自身やスローリストに追加して対処するかを決めることができるかを知るためには、JavaのAPIドキュメントを読んでください。後者の場合には、躊躇しないでください。直接そのプレスより処理し、優れたハンドリングできる例外プロセッサに。
また、覚えておいて、このルールの例外があります。私はすでに言及した:あなたはカバレッジのスーパークラスを作成しますが、この方法は、(このようなpaintComponentのJComponentなど)例外をスローしていない場合、このメソッドは、コードはチェック例外で表示されるすべてのメソッドを取得する必要があります。例外クラスのスーパークラスメソッドが許可サブクラスに記載の範囲には指定をスロー超えます。
2.2複数の例外を捕捉し
tryブロック内の異常の種類、および例外の異なる複数種類の異なる処理さ取り込むことができます。各例外の種類は、次の方法の別のcatch節を使用することができます。
try {
code that might throw exceptions
}
catch (FileNotFoundException e) {
emergency action for missing files
}
catch (UnknownHostException e) {
emergency action for unknown hosts
}
catch (IOException e) {
emergency action for allother I/Oproblems
}
例外オブジェクトは、例外自体に関連する情報を含むことができます。オブジェクトの詳細情報を取得するには、使用しようとすることができます
e.getHessage()
(もしあれば)、詳細なエラー情報を取得する、または使用
e.getClass().getName()
例外オブジェクトの実際の型を取得します。
Java SE 7では、同じことがcatch節の例外タイプの複数捕捉することができます。例えば、不足しているファイルや不明なホスト例外に対応する動作が同じであると仮定し、catch節を組み合わせることができます。
try {
code that might throw exceptions
}
catch (FileNotFoundException|UnknownHostException e) {
emergency action for missing filesand unknown hosts
}
catch (IOException e) {
emergency action for all other I/O problems
}
互いの例外サブクラスのタイプの間には関係が必要な場合にのみ、この機能を取り込むことがないとき。
注意:最後の変数として、暗黙の例外変数を複数の例外を捕捉した場合。例えば、それは、以下の条項体における異なるE値に割り当てることができません。
catch (FileNotFoundException|UnknownHostException e) {...}
注:キャプチャ複数の例外は、あなたのコードがはるかに簡単だけでなく、より効率的に見えることはありません。バイトコードの共通ブロックを生成するだけで、対応するcatch句が含まれています。
2.3はもう一度例外チェーンを投げ
2.4 finally節
コードは例外をスローするとき、残りの処理方法は、コードを終了し、この方法を撤回されます。この方法は、いくつかのローカルリソースを取得した場合、これは彼が知っている唯一の方法であり、これらのリソースは、メソッドを終了する前に回収しなければならないならば、それは資源回復の問題が発生します。一つの解決策は、すべての例外を捕捉し、再スローすることです。2つの場所に割り当てられたリソースをクリアする必要があるので、この解決策は、比較的退屈です。通常のコードで、他の異常コード。
Javaはfinally節でよりよい解決策を持っています。以下は、適切にファイルでJavaを無効にする方法を説明します。あなたはJavaで書かれたデータベースプログラムを使用する場合は、データベースへの接続をクローズするのと同じ技術を使用する必要があります。ボリュームの第4章Ⅱは、より詳細に見ることができます。例外が発生すると、すべてのデータベースが正常に接続が非常に重要です閉じます。
かかわらず、例外が捕捉されているかどうか、コードのfinally節が実行されます。次の例では、プログラムは、すべてのケースでファイルを閉じます。
InputStream in = new FileInputStream(...);
try {
//1
code that might throwexceptions
//2
}
catch (IOException e) {
// 3
show error message
// 4
}
finally {
// 5
in.close();
}
//6
上記のコードでは、次の3つの場合は、finally節があります、次のとおりです。
1)コードが例外をスローしません。この場合、プログラムは、まず、すべてのtryブロック内のコード、およびfinally節のコードを実行します。その後、tryブロックの後の最初の文に進みます。つまり、ラベルの1,2,5,6-の実装。
- 2)catch節をキャプチャするにはスロー。上記の例ではIOExceptionがあります。異常が発生するまでこの場合、プログラムは、tryブロック内のすべてのコードを実行します。このとき、コードのcatch節の実装に回し、tryブロック内のコードの残りの部分をスキップfinally節の最後のコードの例外と一致します。何のcatch節で例外がスローされない場合は、プログラムは、tryブロックの後の最初の文を実行します。ここでは、1,3,4,5,6でラベリング文の実装。catch節が例外をスローした場合、例外はこのメソッドの呼び出し元に戻ってスローされます。ここでは、1,3,5のラベル文の実装。
3)コードが例外をスローしますが、例外がcatch節でキャッチされていません。この場合、プログラムは、tryブロック内のすべての文を実行します、例外が遠くまで投げられます。このとき、tryブロック内のコードの残りの部分をスキップし、finally節の声明と例外がこのメソッドの呼び出し元に投げ。ここでは、1,5のラベリング文の実装。
文が唯一のfinally節することができますが、句をキャッチしていないしてみてください。例えば、この文を以下試してください。
InputStream in = ...;
try {
code that might throw exceptions
}
finally {
in.close();
}
かかわらず、例外がtryブロックに遭遇しているかどうかの、finally節のin.close()ステートメントが実行されます。もちろん、それが再スローされますと、それは別のcatch節でキャッチしなければならない例外が発生した場合。
実際には、我々は、リソースをクローズする必要性を信じて、このように最終的に句を使用することは良い選択です。
以下の詳細な説明は、ヒントを与えられます。
ヒント:ここでは、強くソリューションに従事することが推奨される共同でのtry / catchおよびfinallyブロック/してみてください。これは、コードの明瞭度を向上させることができます。例えば:
InputStrean in = ...; try { try { code that might throw exceptions } finally { in.close(); } } catch (IOException e) { show error message }
インナーtryブロックは、唯一の義務は、入力ストリームを閉じることを確認することです。外側のtryブロックと一つだけの責任ではエラーレポートが表示されていることを確認することです。この設計アプローチだけでなく、明確でなく、エラーがfinally節に現れ報告します機能を持っています。
警告:finally節は、return文が含まれている場合は、「メソッドが戻る前にtryブロックから利用return文の終了を想定し、予期しない結果があるだろう、finally節の内容は、finally節の場合に実行されます。 return文もあり、戻り値は複雑な例の戻り値の元の外観を上書きします。
public static int f(int n) { try { int r = n * n; return r; } finally { if (n = 2) return 0; } }
コールfが(2)、try文ブロック計算結果は、R = 4であり、returnステートメントを実行した場合、しかし、方法の前にtrueを返すだけでなく、最終的に句。原稿カバー4の0、戻り値の戻り値を返しますfinally節。
時には、finally節は、トラブルをもたらすでしょう。たとえば、リソースをクリーンアップするための方法は、例外をスローする可能性があります。あなたは、閉じた流れは、例外処理コードを検出したことを確認するとします。
InputStreai in = ...;
try {
code that might throw exceptions
}
finally {
in.close();
}
さて、tryブロック内のコードは、いくつかの非のIOException例外、発信者の唯一のこのメソッドは対応することができるようにするため、これらの例外をスローしたとします。finallyブロックを実行し、closeメソッドを呼び出します。CLOS方法自体も、IOExceptionをスローすることがあります。これが発生した場合、元の例外がスローされた賛成近いアプローチで失われます。
最初の例外をより面白くなる可能性があるので、これは、問題になります。あなたは適切な治療を行いたい場合は、元の例外を再スロー、コードは非常に面倒になります。次のように:
InputStream in = ...;
Exception ex = null;
try {
try {
code that might throw exceptions
} catch (Exception e) {
ex=e;
throw e;
}
}
finally {
try {
in.close();
} catch (Exception e) {
if (ex = null)
throw e;
}
}
幸いなことに、次のセクションでは、あなたがはるかに容易にリソース7のJava SEプロセスを閉じるように学びます。