ホームページ Java &#&チュートリアル Java における例外とエラー処理の詳細な調査

Java における例外とエラー処理の詳細な調査

Nov 26, 2016 pm 01:27 PM
java 異常な エラー処理

Java の例外処理メカニズムは比較的成熟しています。Java プログラムには例外の可能性がたくさんあります。これらの例外が事前に処理されないと、将来的にプログラムのクラッシュをデバッグすることが不可能になり、その例外を見つけるのが困難になります。例外の場所。この記事では、Java で例外とエラーを処理する方法について説明します。見てみましょう。

例外とエラー:

例外:

Java では、プログラムのエラーは主に構文エラーと意味エラーであり、プログラムをコンパイルして実行するときに発生するエラーを総称して例外と呼びます (VM (仮想マシン))。このようにして、VM はあなた (開発者) が間違いを犯し、それを修正する機会があることを知らせます。例外クラスは Java で例外を表すために使用され、異なる例外クラスは異なる例外を表します。ただし、Java のすべての例外には、Exception と呼ばれる基本クラスがあります。

エラー:

これは、適切なアプリケーションでは傍受できない深刻な問題を指します。ほとんどが異常です。エラーは VM の障害です (ただし、システム レベルのサービスであればどのようなものでも発生する可能性があります)。したがって、エラーの処理は難しく、通常の開発者 (もちろんあなたではありません) はメモリ オーバーフローなどのエラーを処理できません。 例外と同様、エラー クラスは Java でエラーを表すために使用され、異なるエラー クラスは異なるエラーを表します。 ただし、Java のすべてのエラーには、Error という基本クラスがあります。

要約すると、例外とエラーの最も本質的な違いは、例外は開発者が処理できるのに対し、エラーはシステムに固有のものであり、通常は処理できず、プログラマが処理する必要がないということです。

1. 例外は、通常の命令の実行を中断する、プログラムの実行中に発生するイベントです。
2. 許容可能なコード動作から逸脱するアクションまたはインスタンスです。

例外の構造分類:

1 . 実行時例外 (チェックされていない例外)
2. コンパイル時例外 (チェックされた例外)

実行時例外はすべてコンパイル例外です

Java では、Exception と Error は親クラス Throwable に共通するものを持っています。

エラー例外

runtimeException いくつかのサブクラス
1. java.lang.ArrayIndexOutOfBoundsException
配列インデックスの範囲外の例外。配列のインデックスが負の場合、または配列サイズ以上の場合にスローされます。

2. java.lang.ArithmeticException
算術条件例外。例: 整数のゼロ除算など。

3. java.lang.NullPointerException
Null ポインタ例外。この例外は、アプリケーションがオブジェクトが必要な場所で null を使用しようとするとスローされます。例: null オブジェクトのインスタンス メソッドの呼び出し、null オブジェクトの
属性へのアクセス、null オブジェクトの長さの計算、null をスローする throw ステートメントの使用など。

4.例外が見つかりません。この例外は、アプリケーションが文字列形式のクラス名に基づいてクラスを構築しようとしたが、CLASSPAH を走査した後に対応する名前のクラス ファイルが見つからなかった場合にスローされます。

例外処理:

try{}catch{}

try{}catch{}finally{} 例外の有無に関係なく、finally コード ブロックが実行されます

try{}finally{} も使用できます組み合わせて使用​​できますが、最終的に catch{} はできません

注: 継承関係では、サブクラスは親クラスのメソッドをオーバーライドし、例外をスローする範囲を親クラスより広くすることはできません

例外の使用

例外を使用するこの部分は主にデモンストレーション用です。コードは、コードを書く過程で通常遭遇するものです (もちろんごく一部です)。それに光を当ててみませんか。

例 1. この例は主には、2 つのメソッドを比較することによって、例外が発生した後のコードの実行フローを示しています。

public static void testException1() {
int[] ints = new int[] { 1, 2, 3, 4 };
System.out.println("异常出现前");
try {
System.out.println(ints[4]);
System.out.println("我还有幸执行到吗");// 发生异常以后,后面的代码不能被执行
} catch (IndexOutOfBoundsException e) {
System.out.println("数组越界错误");
}
System.out.println("异常出现后");
}
   
/*output:异常出现前数组越界错误常出现后*/
public static void testException2() {
int[] ints = new int[] { 1, 2, 3, 4 };
System.out.println("异常出现前");
System.out.println(ints[4]);
System.out.println("我还有幸执行到吗");// 发生异常以后,他后面的代码不能被执行
}
ログイン後にコピー

まず、この例の欠点を指摘します。 IndexOutofBoundsException はチェックされていない例外なので、キャプチャを表示するために try...catch... する必要はありませんが、私の目的は、キャプチャに対して別の処理メソッドを使用することです。同じ例外を実行して、どのような違いが生じるのか、そしてその結果を確認してください(ここではしばらくしか使用できません)。例外が発生すると、最初のメソッドは try ブロックから飛び出すだけですが、その背後にあるコードは引き続き実行されます。しかし、2 番目の種類は異なり、メソッドから直接飛び出すため、より困難です。最初のメソッドから、try...catch... は「トランザクション」保証であることがわかります。その目的は、異常な状況下でプログラムが完了することを保証することであると同時に、プログラマに通知することでもあります。プログラム情報内のエラーの詳細 (詳細はプログラマの設計に依存する場合があります)。

例 2. 例外を再スローする

public class Rethrow {
public static void readFile(String file) throws FileNotFoundException {
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
System.err.println("不知道如何处理该异常或者根本不想处理它,但是不做处理又不合适,这是重新抛出异常交给上一级处理");
//重新抛出异常
throw e;
}
}
public static void printFile(String file) {
try {
readFile(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
printFile("D:/file");
}
}
ログイン後にコピー

例外の意図は良いので、プログラムを修復してみますが、実際には修復できる可能性は非常に小さいため、エラー情報を記録するためによく使用されます。常に例外を処理することにうんざりしている場合は、例外を再スローすることで軽減される場合があります。この例外を変更せずに次のレベル、つまりこのメソッドを呼び出す人にスローし、彼に考えさせます。この観点から見ると、Java の例外 (もちろんチェック例外のことを指します) は、その出発点は良いものですが、私たちに多くの問題を引き起こしました。

例 3. 例外チェーンと例外損失の使用

ExceptionA,ExceptionB,ExceptionC
public class ExceptionA extends Exception {
public ExceptionA(String str) {
super();
}
}
public class ExceptionB extends ExceptionA {
public ExceptionB(String str) {
super(str);
}
}
public class ExceptionC extends ExceptionA {
public ExceptionC(String str) {
super(str);
}
}
ログイン後にコピー

例外損失の状況:

public class NeverCaught {
static void f() throws ExceptionB{
throw new ExceptionB("exception b");
}
static void g() throws ExceptionC {
try {
f();
} catch (ExceptionB e) {
ExceptionC c = new ExceptionC("exception a");
throw c;
}
}
public static void main(String[] args) {
try {
g();
} catch (ExceptionC e) {
e.printStackTrace();
}
}
}
/*
exception.ExceptionC
at exception.NeverCaught.g(NeverCaught.java:12)
at exception.NeverCaught.main(NeverCaught.java:19)
*/
ログイン後にコピー

なぜ ExceptionC だけが出力され、ExceptionB は出力されないのでしょうか? これを自分で分析する必要があります

上記の状況は、欠落していることに相当します。これは例外であり、トラブルシューティングのプロセスでは非常に不利です。では、上記の状況に遭遇した場合はどうすればよいでしょうか? ここで例外チェーンが登場します。例外情報を保存し、元の例外を失わずに別の例外をスローします。

public class NeverCaught {
static void f() throws ExceptionB{
throw new ExceptionB("exception b");
}
static void g() throws ExceptionC {
try {
f();
} catch (ExceptionB e) {
ExceptionC c = new ExceptionC("exception a");
//异常连
c.initCause(e);
throw c;
}
}
public static void main(String[] args) {
try {
g();
} catch (ExceptionC e) {
e.printStackTrace();
}
}
}
/*
exception.ExceptionC
at exception.NeverCaught.g(NeverCaught.java:12)
at exception.NeverCaught.main(NeverCaught.java:21)
Caused by: exception.ExceptionB
at exception.NeverCaught.f(NeverCaught.java:5)
at exception.NeverCaught.g(NeverCaught.java:10)
... 1 more
*/
ログイン後にコピー

initCause() メソッドは Throwable から継承しているため、この例外チェーンの特性はすべての例外で共有されます。

例 4. クリーンアップ作業

IO、JDBC などのリソースを消費する操作がある場合、クリーンアップ作業は不可欠です。使用後に適切に閉じないと、メモリリークという深刻な結果が生じます。例外が発生した場合、どのような状況であっても、リソースを適切かつタイムリーにクリーンアップできるようにメカニズムを設計する必要があります。これがついにです。

public void readFile(String file) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(file)));
// do some other work
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ログイン後にコピー

例は非常に簡単で、ファイルを読み取る例です。このような例は、JDBC 操作でも非常に一般的です。 (したがって、リソースをタイムリーかつ正しくクリーンアップすることは、プログラマの基本的な資質の 1 つであると思います。)

試してください...最後に、構造は、リソースが正しく閉じられていることを確認する手段でもあります。コードの実行中にリソースのクリーンアップを妨げるどのような例外が発生するかわからない場合は、 try を使用してこの「疑わしい」コードをラップし、最終的にリソースをクリーンアップできます。例を挙げてみましょう:

public void readFile() {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream("file")));
// do some other work
//close reader
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
ログイン後にコピー

この方法と前の方法の違いに注意してください。次の人はできるだけ早くリーダーを閉じる方が良いかもしれません。しかし、reader.close() より前であればいつでも例外が発生する可能性があり、そのようなコード構造では例外の発生を防ぐことができないため、裏目に出ることがよくあります。例外が発生した場所でプログラムが飛び出すため、後続のコードは実行できません (これは上記の例で証明されるはずです)。現時点では、try...finally を使用して次のように変換できます。

public void readFile() {
BufferedReader reader = null;
try {
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream("file")));
// do some other work
// close reader
} finally {
reader.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
ログイン後にコピー

リソースを早めに閉じることは、良い動作です。時間がかかるほど、リソースを閉じるのを忘れる可能性が高くなります。このようにして、try...finally の調整は絶対確実であることが保証されます (面倒だと思わないでください。Java は非常に満足のいくものです)。

別の状況について話しましょう。コンストラクター メソッドでファイルを開いたり JDBC 接続を作成したりする場合、このリソースを他のメソッドで使用したいため、コンストラクター メソッドの早い段階でこのリソースを閉じることができません。では、私たちは迷っているでしょうか? 答えはノーです。次の例を見てください:

public class ResourceInConstructor {
BufferedReader reader = null;
public ResourceInConstructor() {
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream("")));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void readFile() {
try {
while(reader.readLine()!=null) {
//do some work
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void dispose() {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ログイン後にコピー

この部分は少し長くなりますが、例外は確かに使いやすいようで難しいものです。Java には、深く調査する必要があるものがまだたくさんあります。


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのアームストロング数 Javaのアームストロング数 Aug 30, 2024 pm 04:26 PM

Java のアームストロング番号に関するガイド。ここでは、Java でのアームストロング数の概要とコードの一部について説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

See all articles