「Java/substring使用時のエラーと回避方法」の編集履歴(バックアップ)一覧はこちら

Java/substring使用時のエラーと回避方法」(2019/09/16 (月) 16:49:25) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

文字列切り取り関数である「substring」使用時のエラーの原因と回避方法のまとめです。 * 目次 #contents(,fromhere=true) * java.lang.NullPointerException NullPointerExceptionいわゆるヌルポが発生する場合、substringを仕掛けるオブジェクトが「null」つまり空っぽになっています。 ** 例1:関数の戻り値が「null」 #highlight() {{ String s = getValue(); s = s.substring(1, 2); }} 「getValue」関数の戻り値が「null」の場合「NullPointerException」が発生します。 *** 対策1-1:substringの直前にチェックを入れる #highlight() {{ String s = getValue(); if (s != null) { s = s.substring(1, 2); } }} 「getValue」の戻り値がnullでない場合だけsubstringを行うように対策しました。 *** 対策1-2:「getValue」関数の戻り値がnullにならないようにする #highlight() {{ String getValue() { String ret = null; // ・・・関数の処理・・・ if (ret == null) { return "retがnullの場合の値"; } else { return ret; } } }} 「getValue」が戻り値を返すところにチェックを挿入し、戻り値がnullの場合規定の値を返却するよう策しました。 ** 例2:if文の通り具合で「null」になる場合 #highlight() {{ String s = null; if (getHanteiKekka()) { // ・・・判定結果がtrueの場合の処理・・・ s = "hogehoge"; } else { // ・・・判定結果がfalseの場合の処理・・・ } s = s.substring(1, 2); }} 「getHanteiKekka」の戻り値がfalseの場合、「s」に値が設定されず「NullPointerException」が発生します。 *** 対策2-1:すべてのif文のルートでもれなく値を設定する #highlight() {{ String s = null; if (getHanteiKekka()) { // ・・・判定結果がtrueの場合の処理・・・ s = "hogehoge"; } else { // ・・・判定結果がfalseの場合の処理・・・ s = "mogemoge"; } s = s.substring(1, 2); }} 「判定結果がfalseの場合の処理」にも値を設定するように修正したので「NullPointerException」が発生しません。 *** 対策2-1:substringの直前にチェックを入れる 対策1-1と同じなのでコードは省略します。
文字列切り取り関数である「substring」使用時のエラーの原因と回避方法のまとめです。 * 目次 #contents(,fromhere=true) * java.lang.NullPointerException NullPointerExceptionいわゆるヌルポが発生する場合、substringを仕掛けるオブジェクトが「null」(設定されていない)になっています。 ** 例1:関数の戻り値が「null」 #highlight() {{ String s = getValue(); s = s.substring(1, 2); }} 「getValue」関数の戻り値が「null」の場合「NullPointerException」が発生します。 *** 対策1-1:substringの直前にチェックを入れる #highlight() {{ String s = getValue(); if (s != null) { s = s.substring(1, 2); } }} 「getValue」の戻り値がnullでない場合だけsubstringを行うようチェックを追加しました。 実際には「戻り値がnullだった場合にはどうすべきか」というのも考えなければいけません。 *** 対策1-2:「getValue」関数の戻り値がnullにならないようにする #highlight() {{ String getValue() { String ret = null; // ・・・関数の処理・・・ if (ret == null) { return "retがnullの場合の値"; } else { return ret; } } }} 「getValue」が戻り値を返すところにチェックを挿入し、戻り値がnullの場合規定の値を返却するよう修正しました。 「直前の関数がnullを返さない」と分かっていればsubstringの直前にnullチェックする必要はありません。 *** 対策1-3:エラー処理を行う #highlight() {{ try { String s = getValue(); s = s.substring(1, 2); } catch(Exception e) { // ・・・エラー処理・・・ } }} 「getValue」の戻り値がnullだったらエラーになってOK、エラー処理をしてしまえ!という対策です。 この場合「nullチェックしてnullだったらエラーを投げる」の方がよいのかもしれません。 ** 例2:if文の通り具合で「null」になる場合 #highlight() {{ String s = null; if (getHanteiKekka()) { // ・・・判定結果がtrueの場合の処理・・・ s = "hogehoge"; } else { // ・・・判定結果がfalseの場合の処理・・・ } s = s.substring(1, 2); }} 「getHanteiKekka」の戻り値がfalseの場合、「s」に値が設定されず「NullPointerException」が発生します。 *** 対策2-1:すべてのif文のルートでもれなく値を設定する #highlight() {{ String s = null; if (getHanteiKekka()) { // ・・・判定結果がtrueの場合の処理・・・ s = "hogehoge"; } else { // ・・・判定結果がfalseの場合の処理・・・ s = "mogemoge"; } s = s.substring(1, 2); }} 「判定結果がfalseの場合の処理」にも値を設定するように修正したので「NullPointerException」が発生しません。 今回の例ではif文のルートが2通りでしたが、if文が大量にあってルートを網羅しきれない場合はsubstringの直前でチェックするしかないでしょう。 *** 対策2-2:substringの直前にチェックを入れる 対策1-1と同じなのでコードは省略します。 *** 対策2-3:エラー処理を行う 対策1-3と同じなのでコードは省略します。 * java.lang.StringIndexOutOfBoundsException: String index out of range: xxx オブジェクトの文字数が足りない場合のエラーです。 対策は「NullPointerException」の対策に+αの形になります。 ** 例1:関数の戻り値が短い #highlight() {{ String s = getValue(); s = s.substring(1, 2); }} この例では「getValue」関数の戻り値が0~1文字の場合「StringIndexOutOfBoundsException」が発生します。 2文字以上であれば例外は発生しません。 *** 対策1-1:文字数チェックをする #highlight() {{ String s = getValue(); if (s != null && s.length() >= 2) { s = s.substring(1, 2); } }} 「sがnull以外かつ2文字以上の場合」にsubstringを行うように修正しました。 nullチェックを入れているのは、sがnullだと「length」の方でエラーになる可能性があるためです。 *** 対策1-2:「getValue」関数の戻り値が2文字以下にならないようにする #highlight() {{ String getValue() { String ret = null; // ・・・関数の処理・・・ if (ret == null || ret.length() <= 1) { return "retがnullまたは1文字以下の場合の値"; } else { return ret; } } }} こちらも「NullPointerException」の例に+αした内容ですが「戻り値がnullまたは1文字以下の場合」に規定の値を返すように修正してあります。 *** 対策1-3:エラー処理を行う #highlight() {{ try { String s = getValue(); s = s.substring(1, 2); } catch(Exception e) { // ・・・エラー処理・・・ } }} 「getValue」の戻り値が1文字だったらエラーになってOK、エラー処理をしてしまえ!という対策です。 「NullPointerException」の例と同じです。 ** 例2:if文の通り具合で文字数が不足する場合 #highlight() {{ String s = null; if (getHanteiKekka()) { // ・・・判定結果がtrueの場合の処理・・・ s = "hogehoge"; } else { // ・・・判定結果がfalseの場合の処理・・・ s = "m"; } s = s.substring(1, 2); }} 「getHanteiKekka」の戻り値がfalseの場合、「s」が1文字のため例外が発生します。 *** 対策2-1:すべてのif文のルートで文字数が不足するしないように設定する #highlight() {{ String s = null; if (getHanteiKekka()) { // ・・・判定結果がtrueの場合の処理・・・ s = "hogehoge"; } else { // ・・・判定結果がfalseの場合の処理・・・ s = "mogemoge"; } s = s.substring(1, 2); }} 「判定結果がfalseの場合の処理」にも値を設定するように修正したので例外が発生しません。 今回の例ではif文のルートが2通りでしたが、if文が大量にあってルートを網羅しきれない場合はsubstringの直前でチェックするしかないでしょう。 *** 対策2-2:substringの直前にチェックを入れる 対策1-1と同じなのでコードは省略します。 *** 対策2-3:エラー処理を行う 対策1-3と同じなのでコードは省略します。 ** 例3:第2パラメータより第1パラメータの方が小さい #highlight() {{ String s = getValue(); s = s.substring(2, 1); }} これは「3文字目から1文字切り取り」という意図で記述しやすいコードです。 *** 対策2-1:パラメータを適正な値に変更する #highlight() {{ String s = getValue(); s = s.substring(2, 3); }} 「3文字目から1文字切り取り」の場合、パラメータは「2」と「3」が正解です。 これは気合で覚えるしかないです。 ** 例4:第一パラメータが0未満の場合 #highlight() {{ String s = getValue(); int x = getKaishi(); int n = getMojisuu(); s = s.substring(x, x + n); }} 「xからn文字切り取り」という意図の使い方ですが「x」が0未満の場合にも例外が発生します。 パラメータを何らかの処理で決定している場合に発生しやすい例外です。 *** 対策4-1:substringの直前にチェックを行う #highlight() {{ String s = getValue(); int x = getKaishi(); int n = getMojisuu(); if (x >= 0) { s = s.substring(x, x + n); } }} 「x」が0以上の場合にだけsubstringを行うように修正しました。 第2パラメータが「x + n」ではなく「y」などの場合は第2パラメータも含めてチェックを行う必要があります。 *** 対策4-2:0未満の値が設定されないようにする #highlight() {{ int getKaishi() { int ret = 0; // ・・・getKaishiの処理・・・ if (ret < 0) { return 0; } else { return ret; } } }} 「getKaishi」関数を修正し、戻り値に0未満の値が設定されないようにする対策です。 *** 対策4-3:エラー処理を行う 対策1-3と同じなのでコードは省略します。

表示オプション

横に並べて表示:
変化行の前後のみ表示: