記事のディレクトリ
1.エラーの処理
例外処理のタスクは、エラーが発生した場所からこの状況を処理できるエラーハンドラーに制御を移すことです。
考えられるいくつかのエラー:
- ユーザー入力エラー
- デバイスエラー
- 物理的制限(ストレージ)
- コードエラー
1.異常分類
-
RuntimeException:間違った型変換、範囲外の配列アクセス、またはnullポインターアクセス。
-
IOException:ファイルの終了後にデータを読み取ろうとしています。存在しないファイルを開こうとしています。指定された文字列に基づいてClassオブジェクトを検索しようとしていますが、この文字列で表されるクラスは存在しません。
-
チェックされた例外:IOException。コンパイラーは、チェックされたすべての例外に対して例外ハンドラーが提供されているかどうかをチェックします。
-
未チェックの例外:エラーとRuntimeException
2.チェックされた例外を宣言します
メソッドは、ヘッダーで考えられるすべての例外を宣言する必要があります。
public f(String name) throws FileNotFoundException
{
……
}
このコードは、このメソッドが指定されたStringパラメーターに基づいてメソッドを呼び出すことを示していますが、FileNotFoundExceptionをスローする場合もあります。この悪い状況が発生した場合、メソッドは正常に呼び出されませんが、代わりにFileNotFoundExceptionクラスオブジェクトがスローされます。このメソッドが実際にそのような例外オブジェクトをスローする場合、ランタイムシステムは、FileNotFoundExceptionオブジェクトの処理方法を知るために例外ハンドラーの検索を開始します。
- つまり、メソッドは、スローされる可能性のあるすべてのチェック済み例外を宣言する必要があり、チェックされていない例外は制御不能(Error)であるか、回避する必要があります(RuftimeException)。つまり、ErrorとRuntimeExceptionの例外をスローする必要はありませんが、考えられるすべてのIOException例外を考慮する必要があります。
- スーパークラスのメソッドがサブクラスでオーバーライドされる場合、サブクラスメソッドで宣言されたチェック済み例外は、スーパークラスメソッドで宣言された例外よりも一般的であってはなりません(つまり、より具体的な例外がサブクラスメソッドでスローされる可能性があります。 t例外をスローします)。特に、スーパークラスメソッドがチェック例外をスローしない場合、サブクラスはチェック例外をスローできませんが、メソッドコードに表示されるすべてのチェック例外をキャッチする必要があります。
3.例外をスローする方法
- 手順:適切な例外クラスを見つけ、このクラスのオブジェクトを作成して、オブジェクトをスローします。
String readData(Scanner in)throws EOFException
{
...
while(...)
{
if(!in.hasNext())
{
if (n <len))
{
String gripe="Content-length:"+len+",Received:"+n;
throw new EOFException(gripe);//抛出异常
}
}
...
}
return s;
}
メソッドが例外をスローすると、メソッドは呼び出し元に戻ることができません。言い換えれば、返されるデフォルト値やエラーコードについて心配する必要はありません。
4.例外クラスを作成します
Exceptionから派生したクラス、またはExceptionのサブクラスから派生したクラスを定義するだけです。たとえば、IOExceptionから派生したクラスを定義します。従来、定義されたクラスには2つのコンストラクターが含まれている必要があります。1つはデフォルトのコンストラクターで、もう1つは詳細な説明情報を持つコンストラクターです(スーパークラスThrowableのtoStringメソッドはこれらの詳細情報を出力します。これはデバッグに非常に役立ちます)。
2、例外をキャッチ
例外が発生したときにどこにも例外がキャッチされない場合、プログラムは実行を終了し、例外のタイプやスタックの内容などの例外情報をコンソールに出力します。
例外を処理する2つの方法は次のとおりです。
- 1つ目:例外の処理方法がわからない場合は、呼び出し元に例外を渡します。
String readData(Scanner in)throws EOFException
{
...
while(...)
{
if(!in.hasNext())
{
if (n <len))
{
String gripe="Content-length:"+len+",Received:"+n;
throw new EOFException(gripe);//抛出异常
}
}
...
}
return s;
}
- 2番目のタイプ:対処方法を知っている場合は、自分で対処できます
public void read(String filename)
{
try
{
InputStream in= new FileInputStream(filename));
int b;
while((b =in.read())!=-1)
{
process input
}
}
catch (IOException exception)
{
exception.printStackTrace();
}
}
Java APIのドキュメントを注意深く読んで、各メソッドがスローする可能性のある例外の種類を確認してから、それを自分で処理するか、スローリストに追加するかを決定します。後者の場合、躊躇する必要はありません。例外を抑制するよりも、処理のために有能なプロセッサに直接渡す方がよいでしょう。
ただし、スローの使用には制限があります。前述のように、スーパークラスをカバーするメソッドを作成し、このメソッドが例外をスローしない場合、このメソッドは、メソッドコードに表示されるすべてのチェック済み例外をキャッチする必要があります。スーパークラスメソッドにリストされている例外クラスのスコープを超えて、サブクラスのthrows指定子に表示することは許可されていません。
1.複数の例外をキャッチする
複数のcatch句を使用する場合:
try
{
...
}
catch()
{
...
}
catch()
{
...
}
catch()
{
...
}
e.getMessage();//获得更详细的错误信息
e.getClass().getName();//得到异常的实际类型
同じアクションを持つCatch句を組み合わせることができますが、例外タイプ間にサブクラスの関係はあり得ず、例外変数は暗黙的に最終変数です。
try
{
...
}
catch(FileNotFoundException|UnknownHostException e)
{
...
}
catch()
{
...
}
catch()
{
...
}
2.例外と例外チェーンを再度スローします
try
{
...
}
catch(SQLException e)
{
Throwable se = new ServletException("database error");
se.initCause(e);
throw se;
}
例外がキャッチされたら、次のステートメントを使用して元の例外を取得できます。
Throwable e = se.getCause();
例外をログに記録し、変更を加えずに再スローしたい場合があります。
try
{
}
catch(Exception e)
{
logger.log(level,message,e);
throw e;
}
3.finally節
コードが例外をスローすると、メソッド内の残りのコードの処理が終了し、このメソッドの実行が終了します。メソッドがいくつかのローカルリソースを取得し、メソッドだけがそれを知っている場合、メソッドを終了する前にこれらのリソースをリサイクルする必要がある場合、リソースリサイクルの問題が発生します。この問題を解決するには、finally句を使用します。
例外がキャッチされたかどうかに関係なく、finally句のコードが実行されます。
try
{
...
}
catch()
{
...
}
finally
{
...
}
警告:finally句にreturnステートメントが含まれていると、予期しない結果が発生します。returステートメントを使用してtryブロックを終了するとします。メソッドが戻る前に、finally句の内容が実行されます。finish句にreturnステートメントもある場合、この戻り値は元の戻り値を上書きします。
4.リソースを使用してステートメントを試す
try(Scanner in= new Scanner(new FileInputStream"/usr/share/dict/words"),
Printwriter out = new PrintMriter("out.txt")))
{
while (in.hasNext())
{
out.println(in.nextO.toUpperCase();
}
}
ブロックがどのように出ても、出入りは閉じられます。
5.スタックトレース要素を分析します
詳細については、ThrowableインターフェースのAPIを参照してください。