[解決済み] StringIndexOutOfBoundsExceptionとは何ですか?どうすれば直せますか?
質問
これは私のコードです。
private void bringData() {
final TextView mTextView = (TextView) findViewById(R.id.textView);
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://192.168.4.1:8080/";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
mTextView.setText("Response is: "+ response.substring(0,500));
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
mTextView.setText("That didn't work!");
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
}
アンドロイドのドキュメントから与えられたデフォルトです。私はURLだけを変更しました。
これは私のエラーメッセージです。
java.lang.StringIndexOutOfBoundsException: length=28; regionStart=1; リージョン長=499 at java.lang.String.substring(String.java:1931) com.example.my.app.MainActivity$2.onResponse(MainActivity.java:50)にて。 at com.example.my.app.MainActivity$2.onResponse(MainActivity.java:46) at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60) at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30) at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
デバッグ中、私は以下の箇所を確認しました。
mTextView.setText("Response is: "+ response.substring(0,500));
のメッセージは届きますが、テキストビューは更新されず、アプリはクラッシュします。
具体的には、Looper.Javaファイルの中のここでクラッシュしています。
finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
traceTag は 0 です。
文字列の境界が一部おかしいという記事を読みましたが、修正方法がわかりません。
解決方法を教えてください。
Error Message:
java.lang.StringIndexOutOfBoundsException: length=28; regionStart=1;
regionLength=499 at java.lang.String.substring(String.java:1931) at
com.example.my.app.MainActivity$2.onResponse(MainActivity.java:50) at
com.example.my.app.MainActivity$2.onResponse(MainActivity.java:46) at
com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60) at
com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30) at
com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99) at android.os.Handler.handleCallback(Handler.java:751) at
android.os.Handler.dispatchMessage(Handler.java:95) at
android.os.Looper.loop(Looper.java:154) at
android.app.ActivityThread.main(ActivityThread.java:6077) at
java.lang.reflect.Method.invoke(Native Method) at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
エラーの説明
There is an IndexOutOfBound exception occurred in your MainActivity class
Inside second inner class's OnResponse function as shown MainActivity$2onResponse
on line 46 which basically occurred during substring operation in String.java line 1931
which was invoked from StringRequest.deliverResponse at line 60,
which was invoked from StringRequest.deliverResponse at line 30,
which was invoked from ExecutorDelivery.java at line 99,
which intially started from ZygoteInit$MethodAndArgsCaller's run function
and reached up-to main thread of ActivityThread.main=>looper=>handler
実際の理由
で部分文字列を作成しようとするコード
starting index = 0
ending index = 500
しかし、実際の応答文字列の長さは = 28 なので、文字列の長さは 500 文字の部分文字列を作成するのに十分な長さではありません。
解決策:
-
三項演算子で長さを検証する
?:
mTextView.setText("Response is: "+ ((response.length()>499) ? response.substring(0,500) : "length is too short"));
注:三項演算子(
?:
を短く表現したものです。if else
が、それは ステートメントではない ということは、このようにアトミックステートメントとして発生することはできません。INVALID
割り当てがないため((someString.length()>499) ? someString.substring(0,500):"Invalid length");
-
if-else
視認性を向上させるString msg="Invalid Response"; if(response.length()>499){ msg=response.substring(0,500); } mTextView.setText("Response is: "+msg); //or mTextView.setText("Response is: "+response);
IndexOutOfBoundsExceptionとは何ですか?
<ブロッククオート
IndexOutOfBoundsException
のサブクラスです。
RuntimeException
平均
これはチェックされていない例外で、インデックスが
ある種のもの(配列、文字列、ベクトルなど)が外れた場合。
の範囲外です。例えばListを使用します。
のように ドキュメンテーション
List<String> ls=new ArrayList<>(); ls.add("a"); ls.add("b"); ls.get(3); // will throw IndexOutOfBoundsException , list length is 2
予防 :
String str = "";
int index =3;
if(index < ls.size()) // check, list size must be greater than index
str = ls.get(index);
else
// print invalid index or other stuff
インデックスまたは文字列メッセージを使用したクラス・コンストラクタの使用法
public IndexOutOfBoundsException() {
super();
}
public IndexOutOfBoundsException(String s) {
super(s);
}
IndexOutOfBoundsExceptionの他のバリエーション/サブクラスはどれですか?
-
ArrayIndexOutOfBoundsException : 配列が不正なインデックスでアクセスされたことを示します。インデックスが負の値であるか、あるいは配列のサイズ以上である場合です。
int arr = {1,2,3} int error = arr[-1]; // no negative index allowed int error2 = arr[4]; // arr length is 3 as index range is 0-2
予防 :
int num = "";
int index=4;
if(index < arr.length) // check, array length must be greater than index
num = arr[index];
else
// print invalid index or other stuff
-
StringIndexOutOfBoundsException (文字列インデックス境界外例外) : Stringメソッドで、インデックスが文字列のサイズより負か大きい場合にスローされます。charAtメソッドなど一部のメソッドでは、インデックスが文字列のサイズと等しいときにもこの例外がスローされます。
<ブロッククオートString str = "foobar"; // length = 6 char error = str.charAt(7); // index input should be less than or equal to length-1 char error = str.charAt(-1); // cannot use negative indexes
予防 :
String name = "FooBar";
int index = 7;
char holder = '';
if(index < name.length()) // check, String length must be greater than index
holder = name.charAt(index) ;
else
// print invalid index or other stuff
注
length()
は
String
クラスと
length
の連想フィールドです。
array
.
なぜこのような例外が発生するのですか?
-
ネガティブインデックスの使用方法
arrays
またはcharAt
,substring
機能 -
BeginIndexが
0
を作成するための入力文字列の長さより大きいか、またはendIndexを作成するための入力文字列の長さより大きい。substring
またはbeginIndexがendIndexより大きい。 -
いつ
endIndex - beginIndex
よりも小さい。0
- 入力文字列/配列が空の場合
INFO :
JVMの仕事は、適切な例外のオブジェクトを作成し、その例外が発生した場所に
throw
のようなキーワードを使用するか、または、手動で
throw
というキーワードもあります。
if (s == null) {
throw new IndexOutOfBoundsException("null");
}
どうすれば直せますか?
- スタックトレースの解析
- 入力文字列のnullity、length、valid indexの検証
- デバッグやログを利用する
- 汎用例外キャッチブロックの使用
1.) スタックトレースの解析
この記事の冒頭で示したように、スタックトレースは、それが発生した場所、それが発生した理由についての最初のメッセージで必要な情報を提供するので、あなたは単にそのコードをトレースし、必要な解決策を適用することができます。
例えば、以下のような理由です。
StringIndexOutOfBoundsException
を探し、あなたの
package name indicating your class file
そして、その行に行き、その理由を心に留めて、単純に解決策を適用します。
例外とその原因についてもドキュメントで勉強しておくと、先が見えてきますよ。
2.) 入力文字列の空白、長さ、有効なインデックスに対する検証
サーバーからのレスポンス(あるいはエラーか何か)、ユーザーからのレスポンスなど、実際の入力が不明な場合は、想定外のケースをすべてカバーする方がよいでしょう。
でも、テストの限界に挑戦するのが好きなユーザーもいるはずです。
ということで
input!=null && input.length()>0
を使うか、インデックスの場合は三項演算子や
if-else
バウンダリーチェック条件
3.) デバッグやログの活用
デバッグモードでプロジェクトの実行環境をテストするには、プロジェクトにブレークポイントを追加します。
ログはチェックポイントのようなもので、制御がこのポイントを通過すると詳細を生成します。基本的には、システムまたはユーザーによって与えられる情報メッセージで、LogsまたはPrintlnメッセージを使ってロギングメッセージを置くこともできます。
4.) 汎用例外キャッチブロックの使用
Try-catch
ブロックは、常に
RuntimeExceptions
ということで、複数の
catch
ブロックの中で、起こりうる問題を処理し、適切な詳細を与えることができます。
try {
mTextView.setText("Response is: "+ response.substring(0,500));
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
System.out,println("Invalid indexes or empty string");
}
catch (NullPointerException e) { // mTextView or response can be null
e.printStackTrace();
System.out,println("Something went wrong ,missed initialization");
}
catch (Exception e) {
e.printStackTrace();
System.out,println("Something unexpected happened , move on or can see stacktrace ");
}
その他の参考資料
関連
-
[解決済み] android.os.NetworkOnMainThreadException' を修正するにはどうすればよいですか?
-
[解決済み] ストリングビルダー.イコール Java
-
[解決済み] Java の文字列インデックスが範囲外です。0 [閉店]
-
[解決済み] java.sql.SQLRecoverableException: IO エラーです。NL Exceptionが発生しました
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] インスタンス状態の保存を使用してアクティビティ状態を保存するにはどうすればよいですか?
-
[解決済み】「px」、「dip」、「dp」、「sp」の違いは?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】StringIndexOutOfBoundsException 文字列のインデックスが範囲外です。0 [重複]
-
[解決済み] java.lang.StringIndexOutOfBoundsExceptionエラー[重複]を取得する。
-
[解決済み] getContentPane()は具体的に何をするのですか?
-
[解決済み] この配列の中の数字を入れ替えるには、何が足りないのでしょうか?ジャバ
-
[解決済み] javacが「using unchecked or unsafe operations」という警告を出す原因は何ですか?
-
[解決済み] mavenのコンパイルに失敗するのはなぜですか?
-
[解決済み] 1行目2列目でBEGIN_ARRAYを期待したが、BEGIN_OBJECTだった。
-
[解決済み] Java の文字列インデックスが範囲外です。0 [閉店]
-
[解決済み] javaでメソッドを呼び出すプログラムのエラー修正
-
[解決済み] Spring ApplicationContext - リソースリーク: 'context' が閉じられない