異常な
一般的な例外コード:
public class Exception01 {
public static void main(String[] args) {
int n1 = 10;
int n2 = 0;
// n1 / n2 => 10 / 0
int res = n1/n2;
System.out.println("程序继续运行……");
}
}
例外キャプチャ (try-catch) が設定されます。
public class Exception01 {
public static void main(String[] args) {
try{
int n1 = 10;
int n2 = 0;
// n1 / n2 => 10 / 0
int res = n1/n2;
} catch (Exception e){
// TODO:handle exception
//e.printStackTrace();//打印异常堆栈,即将异常出错的代码和信息输出
System.out.println("异常信息=" + e.getMessage());
}
System.out.println("程序继续运行……");
}
}
例外の紹介
基本的な考え方
Java言語では、プログラム実行中に発生する異常事態を「異常」と呼びます。(開発時の構文エラーや論理エラー
も例外ではありません)
異常イベントは 2 つのカテゴリ (エラー、例外) に分類できます。
- エラー (Error) : Java 仮想マシンでは解決できない重大な問題。例: JVM システムの内部エラー、リソースの枯渇、その他の深刻な状況。例: StackOverflow エラースタック オーバーフロー] およびooM (メモリ不足
)、エラーは重大なエラーであり、プログラムはクラッシュします。 - 例外: プログラミング エラーや偶発的な外部要因によって引き起こされるその他の一般的な問題は、特定のコードで処理できます。たとえば、空のフィンガーアクセス、存在しないファイルを読み込もうとした、ネットワーク接続の
中断など。例外は、実行時例外[プログラムの実行中に発生する例外]とコンパイル時例外[コンパイラチェック例外]の 2 つのカテゴリに分類されます。]。
クラス図:
一般的な実行時例外
-
NullPointerException Null ポインタ例外
String name = null; System.out.println(name.length());
-
ArithmeticException 数学演算例外
int n1 = 10; int n2 = 0; int res = n1/n2;
-
ArrayIndexOutOfBoundsException 配列添字の範囲外の例外
int[] arr = { 1, 2, 4}; for (int i = 0; i <= arr.length; i++) { System.out.println(arr[i]); }
-
ClassCastException 型変換例外
public class ClassCastException_ { public static void main(String[] args) { A b = new B();//向上转型 B b2 = (B)b;//向下转型,OK的 C c2 = (C)b;//这里会抛出ClassCastException类型转换异常 } } class A { } class B extends A { } class C extends B { }
-
NumberFormatException 数値形式が正しくない例外
String name = "Jack"; //将 String 解析成 int int num = Integer.parseInt(name);
一般的なコンパイル時の例外
- SQL例外
- IO例外
- ファイルが見つかりません例外
- クラスが見つかりません例外
- EOF例外
- IlldgalArgumentException
例外処理
基本的な紹介
例外処理は、例外が発生したときに例外を処理する方法です。
例外の処理方法
- try-catch-finally
プログラマーはコード内の例外をキャッチし、自分自身で処理します。 - throws は
、発生した例外をスローし、処理のために呼び出し元に渡します。最上位のハンドラーは JVM です。
トライ・キャッチ・最後に
try{
//代码/可能有异常
} catch (Exception e) {
//捕获异常
//1.当异常发生时
//2.系统将异常封装成Exception对象e,,传递给catch
//3.得到异常对象后,程序员自己处理
} finally {
//没有finally语法也是可以通过的
//不管有没有异常,finally一定要执行
}
投げる
例外はデフォルトでスローを使用します。
試してみてください
try-finally を連携のために直接使用することは、例外をキャッチしないことと同じであるため、プログラムは直接クラッシュします。アプリケーション シナリオではコードを実行しますが、例外が発生するかどうかに関係なく、特定のビジネス ロジックを実行する必要があります。
try{
//代码......
} finally {
//总是执行的代码
}
仕組みを試す
TryCatchDetail01.java
ctrl + alt + t
ショートカット キーを使用してtry-catch を設定します
[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-7aIbVacn-1644128312071)(.\image\image-20211007084308512.png)]
public class TryCatch01 {
public static void main(String[] args) {
try {
String str = "Jack";
int a = Integer.parseInt(str);
System.out.println("数字:" + a);
} catch (NumberFormatException e) {
System.out.println("异常信息 = " + e.getMessage());
}
System.out.println("程序继续......");
}
}
何が起こってもコードの一部を実行したい場合は、finally を使用します。
さまざまなビジネス処理のさまざまな例外をキャプチャするために複数の catch ステートメントが存在する場合があります)。これには、親例外が後続し、サブクラス例外が先行する必要があります。たとえば (例外が後続し、NullPointerException が先行します)、例外が発生した場合、一致する catch ステートメントは 1 つだけになります。
TryCatchDetail02.java
public class TryCatchDetail02 {
public static void main(String[] args) {
try {
Person person = new Person();
person = null;
System.out.println(person.getName());//NullPointerException
int n1 = 10;
int n2 = 0;
int res = n1 / n2;//ArithmeticException
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
}
}
}
class Person{
private String name;
public String getName() {
return name;
}
}
複数の例外処理の改善:
サブクラス例外は最初に配置する必要があります。!!
public class TryCatchDetail02 {
public static void main(String[] args) {
try {
Person person = new Person();
person = null;
System.out.println(person.getName());//NullPointerException
int n1 = 10;
int n2 = 0;
int res = n1 / n2;//ArithmeticException
} catch (NullPointerException e) {
System.out.println("空指针异常: " + e.getMessage());
} catch (ArithmeticException e) {
System.out.println("算数异常: " + e.getMessage());
} catch (Exception e) {
System.out.println("一般异常: " + e.getMessage());
} finally {
}
}
}
class Person{
private String name;
public String getName() {
return name;
}
}
TryCatchDetail03.java
public class TryCatchDetail03 {
public static void main(String[] args) {
try{
int n1 = 10;
int n2 = 0;
System.out.println(n1 / n2);
} finally {
System.out.println("执行了finally...");
}
//不会继续运行,程序运行完finally后直接崩溃
System.out.println("程序继续运行...");
}
}
TryCatchExercise01.java
public class TryCatchExercise01 {
public static int method(){
try{
String[] names = new String[3];
if(names[1].equals("tom")){
//NullPointerException
System.out.println(names[1]);
} else{
names[3] = "hspedu";
}
return 1;
}
catch (ArrayIndexOutOfBoundsException e){
return 2;
}
catch (NullPointerException e){
return 3;
}
//由于finally必须执行,则一定返回4
finally{
return 4;
}
}
public static void main(String[] args) {
System.out.println(method());
}
}
TryCatchExercise02.java
public class TryCatchExercise02 {
public static int method(){
int i = 1;
try{
i++;//2
String[] names = new String[3];
if(names[1].equals("tom")){
//NullPointerException
System.out.println(names[1]);
} else{
names[3] = "hspedu";
}
return 1;
}
catch (ArrayIndexOutOfBoundsException e){
return 2;
}
catch (NullPointerException e){
return ++i;//3
}
//由于finally必须执行,则一定返回4
finally{
return ++i;//4
}
}
public static void main(String[] args) {
System.out.println(method());//4
}
}
TryCatchExercise03.java
public class TryCatchExercise03 {
public static int method(){
int i = 1;//1
try{
i++;//2
String[] names = new String[3];
if(names[1].equals("tom")){
//NullPointerException
System.out.println(names[1]);
} else{
names[3] = "hspedu";
}
return 1;
}
catch (ArrayIndexOutOfBoundsException e){
return 2;
}
catch (NullPointerException e){
//返回3
return ++i;//3
}
finally{
++i;//4
System.out.println("i = " + i);//i = 4
}
}
public static void main(String[] args) {
System.out.println(method());//3
}
}
TryCatchExercise04 - 例外キャッチによる入力の取得
public class TryCatchExercise04 {
/* 1.创建Scanner
* 2.使用无限循环去接受一个输入
* 3.然后将输入的值转化为int
* 4.如果在转化时抛出异常,则说明输入内容不能转化为int
* 5.如果没有抛出,则break该循环*/
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num = 0;
while (true) {
System.out.println("请输入一个整数:\n");
try {
num = Integer.parseInt(scanner.next());
break;
} catch (NumberFormatException e) {
System.out.println("输入有误,请重新输入!\n");
}
}
System.out.printf("您的输入为: " + num);
}
}
投げる機構
メソッドが (ステートメントの実行時に) 何らかの例外を生成する可能性があるが、その例外を処理する方法が不明な場合、メソッドは例外がスローされることを明示的に宣言し、メソッドが例外を処理しないことを示す必要があります。
メソッド内で throws ステートメントを使用して、スローされる例外のリストを宣言します。 throws の背後にある例外タイプには、メソッドまたはその親クラスで生成された例外タイプを使用できます。
Throws01.java
public class Throws01 {
public static void main(String[] args) {
}
//public void f1() throws Exception 也可以
public void f1() throws FileNotFoundException, NullPointerException {
//创建了一个文件流对象
//这里的异常是一个FileNotFoundException
//可以使用try-catch
//也可以使用throws,抛出异常,让调用fi方法的调用者()处理
//throws关键字后也可以是列表
FileInputStream fis = new FileInputStream("dd.txt");
}
}
ThrowsDetail.java
-
コンパイル例外の場合は、try-catch や throws などのプログラム内で処理する必要があります。
-
実行時例外の場合、プログラム内に処理がない場合、デフォルトのメソッドは throw です。
-
サブクラスが親クラスのメソッドをオーバーライドする場合、例外をスローするための規則が適用されます。サブクラスによって書き換えられたメソッドによってスローされる例外のタイプは、親クラスによってスローされるものと同じであるか、例外タイプのサブタイプになります。親クラスによってスローされます。
class Father { public void method() throws RuntimeException{ } } class Son extends Father { //子类重写父类的方法时,对抛出异常的规定: // 子类重写的方法所抛出的异常类型要么和父类抛出的一致, // 要么为父类抛出异常类型的子类型。 @Override public void method() throws NullPointerException { } }
コンパイル例外処理
解決策 1: try-catch 処理を使用する
解決策 2: 投げる
例外処理
カスタム例外
プログラム内で何らかの「エラー」が発生したが、そのエラーが Throwable サブクラスに記述されていない場合、この時点で、エラー メッセージを記述する独自の例外クラスを設計できます。
カスタム例外ステップ
- 定義クラス: カスタム例外クラス名、継承
Expection
、またはRnntimeExpection
- 継承された場合、コンパイル例外
Expection
となります。 - 継承した場合は
RuntimeExpection
異常動作(一般継承RuntimeExpection
)
カスタム例外.java
public class CustomExpection {
public static void main(String[] args) {
int age = 800;
//要求年龄在18-120之间1,否则抛出一个异常
if (!(age >= 18 && age <= 120))
{
throw new AgeException("年龄需要在18~120之间!");
}
System.out.println("你的年龄范围正确!");
}
}
//自定义的一个异常
//1.一般情况,自定义异常都是继承RuntimeException,即运行时异常
//2.好处是,我们可以使用默认的处理机制
class AgeException extends RuntimeException {
//构造器
public AgeException(String message) {
super(message);
}
}
投げと投げの違い
意義 | 位置 | 後ろに何か | |
---|---|---|---|
投げる | 例外処理の方法 | メソッド宣言 | 例外の種類 |
投げる | 例外オブジェクトを手動で生成するためのキーワード | メソッド本体 | 例外オブジェクト |