Java例外処理
記事の内容は、Shang Silicon Valley、jdk8、Eclipse環境から選択されています
スローは例外をスローします
Javaでの例外処理。前述のように、Javaで例外を処理する方法は2つあります。1つはtry-catch-finallyブロックを使用して例外を処理する方法、もう1つは例外をスローしてメソッドに渡す方法です。メソッドを呼び出します。
例外のスローの兆候は、スロー例外タイプです。
例外コードに続くコードはまだ実行されていません
サンプルコードは次のとおりです
package com.atguigu.java;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionTest2 {
public static void main(String[] args) {
try {
method2();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
public static void method2() throws FileNotFoundException,IOException{
method1();
}
public static void method1() throws FileNotFoundException,IOException{
File file = new File("hello1.txt");
FileInputStream fis = new FileInputStream(file);
int data = fis.read();
while(data != -1){
System.out.print((char)data);
data = fis.read();
}
fis.close();
}
}
コードを分析すると、元のmethod1メソッドでは、FileNotFoundExceptionとIOExceptionの2種類の問題が発生する可能性があるため、ここでの処理メソッドは、システムによって生成された2つの例外を上向きにスローし、method2メソッドにスローします。method2メソッドの場合は使用されませんtry-catchメソッドは例外を処理するため、例外をmainメソッドに報告する必要があります。実際、mainメソッドをスローしてJVMにスローすることもできます。ただし、通常、mainメソッドはtryを使用する必要があります。 -JVMを防ぐために例外を処理するためのキャッチ例外を処理できず、電話を切ります。
全体として、呼び出し元のメソッドは、呼び出されたメソッドの例外を解決する必要があります。例外をスローする(例外をスローする)ことも、例外を処理するメソッドの1つと見なすことができます。
上記のコードは次のように書くこともできます
package com.atguigu.java;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionTest2 {
public static void main(String[] args) {
try {
method2();
} catch (IOException e){
e.printStackTrace();
}
}
public static void method2() throws IOException{
method1();
}
public static void method1() throws FileNotFoundException,IOException{
File file = new File("hello1.txt");
FileInputStream fis = new FileInputStream(file);
int data = fis.read();
while(data != -1){
System.out.print((char)data);
data = fis.read();
}
fis.close();
}
}
IOExceptionはFileNotFoundExceptionの親クラスであるため、IOExceptionがFileNotFoundExceptionをカバーしていると理解することもできます。したがって、method2が例外をスローする場合、IOExceptionのみを書き込むことができます。mainメソッドでは、IOExceptionのみが処理されます。次に、このメソッドと前のメソッドの違いは、2つの例外処理メソッドが同じである場合、FileNotFoundException例外をスローする必要はなく、IOException例外をスローするだけで、2つの例外処理メソッドが異なる場合は、前のメソッドに従うだけです。 2つの異なる例外を別々に処理するメソッドを記述します。
try-catchメソッドは実際に例外を処理しますが、throwsメソッドはメソッドの呼び出し元に例外をスローするだけで、実際には例外を処理しません。
サブクラスのオーバーライドメソッドによってスローされる例外は、親クラスのオーバーライドメソッドによってスローされる例外より大きくてはなりません。
サンプルコードは次のとおりです
import java.io.FileNotFoundException;
import java.io.IOException;
public class OverrideTest {
}
class SuperClass{
public void method() throws IOException{
}
}
class SubClass extends SuperClass{
public void method() throws FileNotFoundException{
}
}
サブクラスのオーバーライドメソッドによってスローされる例外は、オーバーライドメソッドによって親クラスによってスローされる例外より大きくてはなりません。もちろん、サブクラスは例外をスローすることはできません。
class SubClass extends SuperClass{
public void method() {
}
}
この記述も合法であり、異常は無限に小さいため、異常がないほど小さいため、単純に理解されます。
サブクラスオーバーライドメソッドによってスローされる例外が、オーバーライドメソッドによってスーパークラスによってスローされる例外より大きくてはならない理由は、ポリモーフィズムを使用する場合、親クラスの例外が次の例外をカバーできることを確認する必要があるためです。サブクラス。デモコードは次のとおりです。
package com.atguigu.java;
import java.io.FileNotFoundException;
import java.io.IOException;
public class OverrideTest {
public static void main(String[] args) {
OverrideTest test = new OverrideTest();
test.display(new SubClass());
}
public void display(SuperClass s){
try {
s.method();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class SuperClass{
public void method() throws IOException{
}
}
class SubClass extends SuperClass{
public void method() {
}
}
ポリモーフィズムを使用する場合、サブクラスが例外をスローする場合、例外タイプは親クラスの例外タイプ以下でなければなりません。
開発中の例外を処理する方法を選択する方法
- サブクラスのオーバーライドメソッドによってスローされる例外は、親クラスのオーバーライドメソッドによってスローされる例外より大きくてはならず、スローされない例外は最小の例外として理解されると言いました。クラスはスローしません例外が発生した場合、サブクラスで例外をスローすることは許可されておらず、try-catchの方法でのみ処理できます。
- 3つのメソッドa、b、およびcが漸進的な関係にある場合、つまり、メソッドaの結果がメソッドbによって呼び出され、メソッドbの結果がメソッドcによって呼び出される場合、これらの3つのメソッドは次の場合に最適に使用されます。スローを宣言すると、例外がスローされます。dメソッドが3つのメソッドa、b、およびcを呼び出す場合は、3つのメソッドa、b、およびcをtry構造体に入れて、問題を解決します。a、b、cの3つのメソッドが宣言されているときにtry-catchを使用すると、コンパイラは確実に合格できますが、論理的には問題が発生する可能性があります(a、b、cの3つのメソッドはプログレッシブ関係であるため) )の場合、操作の結果は間違いなく正しくありません。論理的な混乱を避けるために、dメソッドでtry-catch構造を使用して、統一された方法で例外を解決することをお勧めします。
- try-catchとthrowsは、例外を処理する2つの方法です。try-catchが問題を解決してからスローするため、これらを一緒に使用しないことをお勧めします。このメソッドを呼び出すメソッドは、try-catch構造を記述する必要があります。例外を処理します。
- 繰り返しになりますが、実行時の例外を解決するために、try-catchは通常、例外の処理には使用されませんが、例外を処理するようにコードを変更します。try-catchは、問題がどこにあるかをユーザーに通知するエラーメッセージとして機能しますが、実際には使用できません。例外を処理します。
例外を手動で処理する
例外オブジェクトを生成する方法は2つあります。1つはシステムによって自動的に生成される(スロー)方法、もう1つは手動で例外オブジェクトを生成してスローする(スローする)方法です。
例外オブジェクトを手動でスローするための特定のアプリケーションシナリオがあります。デモコードは次のとおりです。
package com.atguigu.java2;
public class StudentTest {
public static void main(String[] args) {
Student s = new Student();
s.regist(-1001);
System.out.println(s);
}
}
class Student{
private int num ;
public void regist(int num){
if(num > 0)
this.num = num;
else
System.out.println("输入格式非法");
}
@Override
public String toString() {
return "Student [num=" + num + "]";
}
}
操作の結果は次のとおりです。
不正な入力形式
Student [num = 0]
通常は正の数を入力すると、Student [num =正の数の値]が直接出力されます。これは、toStringの書き換えられたコンテンツです。
ただし、ここでは負の数を入力し、入力形式は不正であり、toStringメソッドを呼び出して値を出力する必要がなくなったため、手動で例外をスローする必要があります。
手動で例外をスローするオブジェクトのタイプ
手動でスローされる例外オブジェクトには、RuntimeExceptionとExceptionの2種類があります。
RuntimeException
これはランタイム例外であるため、コンパイラはRuntimeExceptionを検出してもエラーを報告しません。例外がチェックされている場合、エラーが報告されます。
class Student{
private int num ;
public void regist(int num){
if(num > 0)
this.num = num;
else
// System.out.println("输入格式非法");
throw new RuntimeException("输入格式非法");
}
操作の結果
、コンパイラーは実行時例外が処理されないことを検出するため、コンパイル時にエラーを報告しません。実行時例外は実行時にのみ報告されます。
Alt + /を押して、例外タイプのコンストラクターを表示します。RuntimeExceptionクラスにはRuntimeException(String arg0)というコンストラクターがあるため、文字列を挿入すると、その文字列がコンソールに出力されます。前のテキストe.getMessage()メソッドについて説明します。
例外
Exceptionオブジェクトを手動でスローすることもできます。Exceptionはランタイム例外ではないため、ランタイム例外とコンパイル時例外の親クラスです。例外がコンパイル時に処理されない場合、コンパイラはエラーを報告します。
package com.atguigu.java2;
import javax.management.RuntimeErrorException;
public class StudentTest {
public static void main(String[] args) {
Student s = new Student();
try {
s.regist(-1001);
} catch (Exception e) {
// e.printStackTrace();
System.out.println(e.getMessage());
}
System.out.println(s);
}
}
class Student{
private int num ;
public void regist(int num) throws Exception{
if(num > 0)
this.num = num;
else
// System.out.println("输入格式非法");
// throw new RuntimeException("输入格式非法");
throw new Exception("输入格式非法");
}
@Override
public String toString() {
return "Student [num=" + num + "]";
}
}
操作の結果は次のとおりです。
不正な入力形式
スローでのレジストの方法は、手動で例外オブジェクトをスローすることであり、スローでメソッド宣言私たちは、例外の処理方法の一つである、とのtry-catch構造は、mainメソッドで例外を処理するために使用されます。
Exceptionはthrowableの親クラスを継承するため、e.getMessage()はthrowableの親クラス構造を呼び出すメソッドです。
public String getMessage() {
return detailMessage;
}
ここでのExceptionのコンストラクターは
public Exception(String message) {
super(message);
}
スロー可能な親クラスから継承
public Throwable(String message) {
fillInStackTrace();
detailMessage = message;
}
したがって、コンストラクターによって割り当てられた値は、e.getMessage()メソッドによって出力できます。
ユーザー定義の例外
ユーザー定義の例外は、Javaライブラリの例外オブジェクトの書き込みメソッドを参照することで書き込むことができます。
- ユーザー定義の例外は、RuntimeExceptionおよびExceptionから継承できます。
- ユーザー定義の例外には、クラスの識別子として理解されるグローバル定数serialVersionUID(シリアル番号)が必要です。
- オーバーロードされたコンストラクターを提供する
package com.atguigu.java2;
public class MyException extends RuntimeException{
static final long serialVersionUID = -70348971907766939L;
public MyException(){
}
public MyException(String msg){
super(msg);
}
}
前のコードで変更します
public void regist(int num) throws Exception{
if(num > 0)
this.num = num;
else
// System.out.println("输入格式非法");
// throw new RuntimeException("输入格式非法");
// throw new Exception("输入格式非法");
throw new MyException("不能输入负数");
}
操作の結果は次のとおりです。
負の数は入力できません
MyExceptionは実行時例外であり、実行時例外は処理されない場合があり、コンパイラーはエラーを報告しないことに注意してください。MyExceptionはRuntimeExceptionを継承するため、Exceptionをスローせずに実行できます。(スローされたExceptionはMyExceptionの親クラスであり、legalです)(throwsは例外を処理するメソッドの1つでもあります)
public void regist(int num) {
if(num > 0)
this.num = num;
else
// System.out.println("输入格式非法");
// throw new RuntimeException("输入格式非法");
// throw new Exception("输入格式非法");
throw new MyException("不能输入负数");
}
これは合法であり、操作の結果は次のとおりです。
負の数は入力できません
MyExceptionがExceptionから継承されている場合は、registメソッドで手動でスローされた例外をすぐに処理する必要があります。そうしないと、コンパイラがエラーを報告します。
public class MyException extends Exception{
registメソッドでthrowまたはtry-catch処理を実行します。
public void regist(int num) throws MyException {
if(num > 0)
this.num = num;
else
// System.out.println("输入格式非法");
// throw new RuntimeException("输入格式非法");
// throw new Exception("输入格式非法");
throw new MyException("不能输入负数");
}
MyExceptionの親クラスであるExceptionをスローすることも合法です。