English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
先生が言ったように、今後の学習ではほとんどの例外が空指針例外です。だから、ゲームを少しやる時間を取って空指針例外とは何かを調べてみましょう
一:空指針例外が発生する主な原因は以下の通りです:
(1)オブジェクトが存在しない場合にそのメソッドを呼び出すと例外が発生しますobj.method() // objオブジェクトが存在しません
(2)オブジェクトの存在しないフィールドにアクセスまたは修正を試みると例外が発生しますobj.method() // methodメソッドが存在しません
(3)文字列変数が初期化されていない場合:
(4)インターフェースのオブジェクトが具体的なクラスで初期化されていない場合:
List lt;するとエラーが発生します
List lt = new ArrayList();するとエラーは発生しません
オブジェクトの値が空である場合、空であることを判断していない場合があります。以下のコードの前に一行のコードを追加してみてください:
if(rb!=null && rb!="")
変更して:
if(rb==null); if(rb!==null&&rb!="") または if((「」).equals(rb))
空指針の解決策:
エラーが発生した行に注目し、空指針例外が発生する2つの主な原因を診断して具体的なエラーを特定します。また、空指針の発生を避けるために、判断処理を行う際には「null」または空値を設定値の前に置くことをお勧めします。
一般的な空指針例外の簡単な分析:
(1)空指針エラー Java.lang.NullPointerException
Javaでは、8基本データ型の変数にはデフォルト値があります。そのため、正常に値を割り当てない場合でも、Java仮想機は正しくコンパイルを通過できません。したがって、基本的なJavaデータ型を使用する場合、空指針例外が発生することは稀です。実際の開発では、大多数の空指針例外はオブジェクトの操作に関連しています。
二、Javaの例外処理メカニズム
例外が発生する可能性のあるコードに対して、2つの処理方法があります:
第一、メソッド内でtry...catch文を使用して例外をキャッチし処理します。catch文は複数設定可能で、複数の例外に対応できます。例えば:
public void p(int x){ try{ ... }catch(Exception e){ ... }finally{ ... }}
第二、処理できない例外や変換する必要のある例外については、メソッドの宣言部分で以下のように
throws 文で例外を投げます。例えば:
public void test1() throws MyException{ ... if(....){ throw new MyException(); }}
各メソッドが単純に例外を投げる場合、メソッドの呼び出しの多層嵌套中で、Java 虚拟機は例外が発生したメソッドのコードブロックから逆方向に探し、例外を処理するコードブロックを見つけるまで戻ります。そして、例外を対応するcatch 文に引き渡します。Java 虚拟機がメソッド呼び出しスタックの最下部のmain()メソッドに達し、まだ例外を処理するコードブロックを見つけていない場合、以下の手順で処理します:
第一、例外を発生させたオブジェクトのprintStackTrace()メソッドを呼び出し、メソッド呼び出しスタックの例外情報を印刷します。
第二、例外が発生したスレッドがメインスレッドである場合、プログラムの実行が終了します;それ以外のスレッドの場合、そのスレッドが終了し、他のスレッドは続行します。
分析と思考を通じてわかるように、例外を早く処理することで消費されるリソースと時間が少なくなり、影響する範囲も小さくなります。したがって、自分が処理できる例外も呼び出し元に投げることが避けられます。
もう一つ、無視すべきことはありません:finally 文はどんな状況でも必ず実行されるコードがあり、それにより、どんな状況でも必ず実行されるコードの信頼性を保証します。例えば、データベースクエリの例外発生時には、JDBC コネクションを解放するなどです。finally 文はreturn 文よりも前に実行されますが、その位置やtry ブロックに例外が発生するかどうかに関係ありません。finally 文が実行されない唯一の状況は、メソッドがSystem.exit()メソッドを実行した場合です。System.exit()は、現在動作しているJava 虚拟機を終了します。finally ブロック内で変数に新しい値を割り当てることでreturnの戻り値を変更することはできません。また、finally ブロック内でreturn 文を使用することも推奨されません。それは無意味であり、エラーを引き起こしやすくなります。
最後に、例外処理の文法規則に注意する必要があります:
第一、try 文は独立して存在することができず、catch、finally と組み合わせて使用できます。
try...catch...finally、try...catch、try...finally の3つの構造体があり、catch 文は1つまたは複数、finally 文は最大1つが指定できます。これらのキーワード(try、catch、finally)はそれぞれ独立して使用することはできません。
二、try、catch、finallyの3つのコードブロックの変数の範囲はそれぞれ独立しており、互いにアクセスすることはできません。これらのブロックで変数を共有するには、これらのブロックの外に変数を定義する必要があります。
三、複数のcatchブロックがある場合、Java仮想機はその例外クラスまたはそのサブクラスをマッチングし、そのcatchブロックを実行します。他のcatchブロックは実行されません。
四、throw文の後には他の文を続けることはできません。これらの文は実行する機会がありません。
五、あるメソッドが宣言して例外をスローする別のメソッドを呼び出した場合、そのメソッドは例外を処理するか、または例外を宣言してスローする必要があります。
2.2throwとthrowsの違い:
throwは、メソッド内で例外をスローするために使用されます。構文はthrow例外オブジェクトです。
throwsは、メソッドが何かの例外をスローする可能性があることを宣言するために使用されます。メソッド名の後で、構文は以下の通りです:
throws例外タイプ1、例外タイプ2...例外タイプn。
三:以下に空指針例外が発生する可能性があるいくつかの状況とその解決策を示します:
コードセグメント1:
out.println(request.getParameter("username"));
分析:コードセグメント1の機能は非常に単純で、ユーザーが入力した「username」の値を出力するだけです。
説明:見た目では、上記の文は何か语法エラーが見つかりませんし、大多数の場合問題も発生しません。しかし、ユーザーがデータを入力する際にフォームフィールド"username"の値を提供していない場合や、フォームを通じて直接入力する方法を避けた場合、このrequest.getParameter("username")の値は空になります(空文字列ではなく、空オブジェクトnullです)。そのため、outオブジェクトのprintlnメソッドは空オブジェクトに対して直接操作することはできません。したがって、コードセグメント1のJSPページでは"Java.lang.NullPointerException"エラーが発生します。また、オブジェクトが空である可能性がある場合でも、Java.lang.ObjectまたはObjectオブジェクト自身のメソッド、例えばtoString()、equal(Object obj)などの操作を呼び出します。
コードセグメント2:
String userName = request.getParameter("username"); If (userName.equals("root")) {....}
分析:コードセグメント2の機能は、ユーザーが提供したユーザー名が"root"のユーザーである場合に特別な操作を実行することを検出します。
説明:では、2中で、ユーザーがフォームフィールド"username"の値を提供していない場合、userNameという文字列オブジェクトはnull値になります。そのため、nullのオブジェクトを別のオブジェクトと直接比較することはできません。同様に、コードセグメント2のJSPページでは空指針エラーが発生します。
一つの小さなテクニックです:あるメソッドの戻り値を定数と比較する場合、定数を前に置くとnullオブジェクトのequalsメソッドを呼び出すことを避けることができます。例えば:
If ("root".equals(userName)) {....}
userNameオブジェクトがnullオブジェクトを返した場合でも、ここでは空指針例外が発生しません。通常通り動作します。
コードセグメント3:
String userName = session.getAttribute("session.username").toString();
分析:コードセグメント3の機能は、セッション内のsession.usernameの値を取得し、その値をuserNameという文字列オブジェクトに割り当てることです。
説明:一般的に、ユーザーが既にセッションを行っている場合、何の問題も発生しません;しかし、アプリケーションサーバーが再起動し、ユーザーが再ログインしていない場合(ユーザーがブラウザを閉じたが、元のページをまだ開いている場合も含まれます。)それに、そのセッションの値が無効化され、セッション内のsession.usernameの値が空になります。nullのオブジェクトに対してtoString()操作を直接実行すると、システムが空指針例外をスローします。
コードセグメント4:
public static void main(String args[]){ Person p=null; p.setName("張三"); System.out.println(p.getName()); }
分析:Personオブジェクトを宣言し、その中のName名を出力します。
説明:この時点であなたのpは空指針例外が発生します。なぜなら、あなたはPersonタイプのオブジェクトを宣言しただけで、実際にオブジェクトを作成していないからです。そのため、そのヒープにはアドレスリファレンスが存在しないため、オブジェクトメソッドを呼び出す際には常にオブジェクトを作成する必要があります。
A: オブジェクトが空であっても直接使用を開始します。
(JSP)コードセグメント1:
out.println(request.getParameter("username"));
分析:コードセグメント1の機能は非常に単純で、ユーザーが入力した「username」の値を出力するだけです。
説明:見たところ、上記の文には文法的なエラーは見られませんし、ほとんどの場合問題も発生しません。しかし、ユーザーがフォームフィールド「username」の値を提供しなかった場合や、フォームを迂回して直接入力した場合、このrequest.getParameter("username")の値は空です(空文字列ではなく、空オブジェクトnullです)。そのため、outオブジェクトのprintlnメソッドは空オブジェクトに対して直接操作できません。そのため、以下のコードセグメント1現在のJSPページでは "Java.lang.NullPointerException" 異常が発生します。また、オブジェクトが空である可能性がある場合でも、Java.lang.ObjectまたはObjectオブジェクト自体のメソッド、例えばtoString()、equal(Object obj)などの操作を実行します。
(JSP)コードセグメント2:
String userName = request.getParameter("username"); If (userName.equals("root")) {....}
分析:コードセグメント2の機能は、ユーザーが提供したユーザー名が"root"のユーザーである場合、特別な操作を実行することを検出します。
説明:では、2では、ユーザーがフォームフィールド"username"の値を提供していない場合、userNameという文字列オブジェクトはnull値になり、nullのオブジェクトを別のオブジェクトと直接比較することはできません。同様に、コードセグメント2のJSPページは(Java.lang.NullPointerException)空ポインタエラーをスローします。
(JSP)コードセグメント3:
String userName = session.getAttribute ("session.username").toString();
分析:コードセグメント3の機能は、セッション内のsession.usernameの値を取得し、その値をuserNameという文字列オブジェクトに割り当てることです。
説明:一般的に、ユーザーがセッションを開始した場合、何の問題も発生しませんが、アプリケーションサーバーが再起動し、ユーザーが再ログインしていない場合(ユーザーがブラウザを閉じたが、元のページがまだ開いている場合もありえます。)その場合、そのセッションの値が無効になり、セッション内のsession.usernameの値が空になります。nullのオブジェクトに対してtoString()を直接実行すると、システムが(Java.lang.NullPointerException)空ポインタ例外をスローします。
これは編集者が皆さんに提供する軽くてjavaのnullポインタ例外の処理についてのガイドの全てです。皆さん、ナイアラガイドを応援してください~