目次
1.例外とは
例外は、プログラムの実行中に発生する一種のエラーです。例外にはさまざまな種類があり、それぞれが異なる意味を表しています。特定の例外が発生すると、プログラマーに例外の理由が明確に示されるため、問題の解決に役立つ良い方法です。
第二に、防御的プログラミング(例外が導入された理由)
1.防御プログラミングとは
プログラムを実行する過程で、プログラムに現在エラーがない場合でも、将来エラーが発生しないという意味ではなく、他の人のマシンで実行したときにエラーが発生しないという意味でもありません...ですから、これらの問題をできるだけ回避するために、プログラムを書くときは、まず「負ける前に口に出さない」という、どのような問題が発生するのかをいろいろ考えてから、対応する必要があります。これらの問題の解決策。このように、それは防御的なプログラミングです。
2.防御プログラミングの2つの特定のコードの兆候
例として王を取り上げます。
①LBYL(例外なし):飛躍の前を見る:操作前に十分なチェックを行ってください。前のステップをチェックした後、次の操作を行ってください。前のステップが失敗した場合、実行は続行されません。
boolean ret=login();
if(!ret){
//处理登录失败
return;
}
ret=startMatch();
if(!ret){
//处理匹配失败
return;
}
ret=enterRoom();
if(!ret){
//处理进入房间失败
return;
}
ret=chooseHero();
if(!ret){
//处理选择英雄失败
return;
}
② EAFP(用法異常):それは許可よりも許しを依頼する方が簡単です最初のカットをし、後で再生します。
try{
login();
startMatch();
enterRoom();
chooseHero();
...
}catch(XXX){
//处理异常的代码
}
分析:特定のステップでエラーが発生した場合、例外がスローされます。例外がスローされると、catchなどのコードを入力して、例外処理ロジックを実行します。
上記の2つの方法のうち、2番目の方法の方が優れていることがわかります。これにより、プログラムの通常のフローがエラー処理から分離され、より明確で理解しやすくなります。
三、例外の特定の文法
1.試してみてください
例外をスローする可能性のあるコードを配置する
2.キャッチ
例外の処理に使用するコードを配置し、tryで使用します。tryで例外が発生すると、キャッチを入力して実行します。
例①
int[] a=null;
System.out.println(a[0]);
System.out.println("hello");
運転結果
分析:コードに例外があり、try catchが使用されていない場合、例外はJVM自体によって処理され、プログラムは直接終了し、ダウンしません。
例②
try{
System.out.println("try中异常之前的代码");
int[] a=null;
System.out.println(a[0]);
System.out.println("try中异常之后的代码");
}catch(NullPointerException e){
System.out.println("catch中的代码");
}
System.out.println("hello");
運転結果
分析:実行順にキャッチを試行:例外が発生した場合は、順次コード実行を押してみます->実行はキャッチに進みます(残りのコードは実行されません)->キャッチも実行されると、で実行されます後続のコードでは、プログラムは異常終了しませんでした。
例③
キャッチ内の例外のタイプは、正しく処理できるようにスローされた例外のタイプと一致する必要があります。一致しない場合、キャッチ内のロジックを実行できず、JVMがそれ自体を処理します。
try{
System.out.println("try中异常之前的代码");
int[] a=null;
System.out.println(a[100]);
System.out.println("try中异常之后的代码");
}catch(NullPointerException e){
System.out.println("catch中的代码");
}
System.out.println("hello");
運転結果
分析:a [100]これは配列添え字の範囲外例外であり、nullポインター例外ではないため、一致がなく、キャッチは処理されず、JVMによって処理され、プログラムは次のようになります。直接終了しました。
例④
複数の例外をキャッチするにはcatchを使用します(|)
try{
System.out.println("try中异常之前的代码");
int[] a=null;
System.out.println(a[100]);
System.out.println("try中异常之后的代码");
}catch(NullPointerException | ArrayIndexOutOfBoundsException e){
System.out.println("catch中的代码");
}
System.out.println("hello");
分析:|を使用して、「論理OR」と同等の複数の例外のタイプを並列化します。これらの例外のいずれかをスローすると、キャッチがトリガーされます。
例⑤
複数の例外をキャッチするためのより絶対的な方法があります(Exception)
try{
System.out.println("try中异常之前的代码");
int[] a=null;
System.out.println(a[100]);
System.out.println("try中异常之后的代码");
}catch(Exception e){
System.out.println("catch中的代码");
}
System.out.println("hello");
分析:例外は非常に高レベルの親クラスです。ヌルポインター例外と配列添え字の範囲外例外はすべてExceptionのサブクラスです。キャッチマッチングの場合、型は必ずしも完全に同じである必要はありません。例外がcatchパラメーターを除いてスローされたサブクラスも可能です(基本的にアップキャスト)。例外は致命的であり、すべての例外が同じロジックで強制的に処理されるため、通常、例外の使用はお勧めしません。
3.最後に
最終的に配置されたコードが実行され、通常、ファイルを閉じるなどの例外処理後の作業を終了するために使用されます。
例①
finalを使用してtrycatchの後ろに配置すると、finallyのロジックが実行されることが保証されます。
try{
System.out.println("try中异常之前的代码");
int[] a={1,2,3};
System.out.println(a[100]);
System.out.println("try中异常之后的代码");
}catch(NullPointerException e){
System.out.println("catch中的代码");
}finally {
System.out.println("hello");
}
分析:前のコードで例外がトリガーされたかどうかに関係なく、finallyのロジックが実行されます。a [100]は配列添え字の範囲外の例外ですが、catchのパラメーターの型はnullポインター例外であり、型が一致しない場合、JVMがそれを処理し、最終的にはまだ実行されます。したがって、ファイルを閉じる操作を最終的に行うことができます。
注:finallyにreturnステートメントを書き込むことはお勧めしません。tryにreturnステートメントがあり、finallyにreturnステートメントがある場合、tryの元のreturnステートメントの代わりにfinallyのreturnステートメントが実行されます。
例②
最終的にリソースをリサイクルするために使用する方が確かに信頼性が高くなりますが、コードの記述はより面倒です。Java1.7が提供するtry withresourceメカニズムを使用してこの操作を完了することもできます。(リソースのリサイクルに責任を持つようにしてください)
try(Scanner sc=new Scanner(System.in)){
int num=sc.nextInt();
System.out.println(num);
}catch (InputMismatchException e){
System.out.println("输入类型不匹配异常");
}
分析:tryの()にScannerオブジェクトを作成して、tryの実行後にScannerのcloseメソッドが自動的に呼び出されるようにします。
4.投げる
例外オブジェクトを積極的にスローします
例①
public class Test2 {
public static int divide(int x,int y){
if(y==0){
throw new ArithmeticException("此处抛出了一个算数异常");
}
return x/y;
}
public static void main(String[] args) {
try{
int ret=divide(10,0);
}catch(ArithmeticException e){
e.printStackTrace();
}
}
}
printStackTrace()メソッドは、例外に関する特定の情報を取得できます。
5.スロー
アノテーションメソッドはいくつかの例外をスローする可能性があります
public class Test2 {
public static int divide(int x,int y) throws ArithmeticException{
if(y==0){
throw new ArithmeticException("此处抛出了一个算数异常");
}
return x/y;
}
public static void main(String[] args) {
try{
int ret=divide(10,0);
}catch(ArithmeticException e){
e.printStackTrace();
}
}
}
分析:スローは除算メソッドをマークします。除算メソッドがArithmeticExceptionをスローする可能性があることを明確に認識し、これらの例外を注意深く処理するようにメソッドの呼び出し元に思い出させます〜
4、Javaの例外システム
1.Javaの例外システムとは
Java標準ライブラリで提供される例外クラスを説明するために使用され、それらのタイプに分けられます。
注意:
- 図の上向き矢印は、実際には「継承」や「実装」などの関係です。
- エラーはシステムレベルの例外であり、JVMによって内部的に使用されます。通常のプログラマーは、エラーシステムを使用しないでください。
- 例外はアプリケーションレベルの例外であり、通常のプログラマーはこの一連のシリーズを使用したいと考えています。
2.チェックされた例外とチェックされていない例外
Java言語仕様は非チェック例外と呼ばれるすべての例外のクラスErrorまたはのRuntimeExceptionクラスから派生し、他のすべての例外は、例外を確認呼ば。
未チェックの例外:
- 処理を表示できません
- エラー:エラーは非常に深刻な状況である必要があります。通常、JVMマシンはハングします。現時点では、アプリケーションレベルのプログラマーとして、それ自体を回避する以外に方法はありません。
- RuntimeException:影響がほとんどない、最も一般的な例外のいくつか。
調査中の例外:
- この例外がメソッドでスローされた場合、例外を明示的に処理する必要があります
- 2つのスキームがあります。①throwsステートメントを使用してcatch②を直接試行すると、この例外がスローされる場合があります。
3.カスタム例外
カスタム例外は通常、Exception(チェック済み)またはRuntimeException(チェックなし)から継承します。
例:単純なコンソールバージョンのユーザーログインプログラムを実装すると、プログラムはユーザーにユーザー名とパスワードの入力を求めるプロンプトを表示します。ユーザー名とパスワードが間違っている場合は、カスタム例外メソッドを使用して対処します。
カスタムNameException:
public class NameException extends Exception{
public NameException(String str){
super(str);
}
}
カスタムPasswdException:
public class PasswdException extends Exception{
public PasswdException(String str) {
super(str);
}
}
テストクラス
import java.util.Scanner;
public class Test {
private static String userName="ttlxbb";
private static String userPassword="5201314";
//主类
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入姓名");
String name=sc.next();
System.out.println("请输入密码");
String password=sc.next();
try{
login(name,password);
}catch(NameException | PasswdException e){
e.printStackTrace();
}
}
//login类
public static void login(String name,String password)throws NameException, PasswdException {
if(!name.equals(userName)){
throw new NameException("用户名输入错误");
}
if(!password.equals(userPassword)){
throw new PasswdException("用户密码输入错误");
}
System.out.println("登录成功!");
}
}
運転結果
分析:ログインメソッドの背後でNameExceptionとPasswdExceptionがスローされ、ログインメソッドがこれら2つの例外をスローする可能性があることを示しています。次に、例外オブジェクトがスローされ、処理のために上位の呼び出し元に渡されます。