What is a StringIndexOutOfBoundsException? How can I fix it?
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)
Error Description
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
Actual Reason
Your code trying to create a substring with
starting index = 0
ending index = 500
though your actual response string length is = 28, so String length is not long enough to create a substring of 500 characters.
Solutions :
Validate length using ternary operator
?:
mTextView.setText("Response is: "+
((response.length()>499) ? response.substring(0,500) : "length is too short"));Note : Ternary operator (
?:
) is a short expression ofif else
but it is not a statement mean it cannot occur as an atomic statement as this isINVALID
because there is no assignment((someString.length()>499) ? someString.substring(0,500):"Invalid length");
if-else
enhances the visibilityString msg="Invalid Response";
if(response.length()>499){
msg=response.substring(0,500);
}
mTextView.setText("Response is: "+msg);
//or mTextView.setText("Response is: "+response);
What is IndexOutOfBoundsException?
IndexOutOfBoundsException
is a subclass ofRuntimeException
mean
it is an unchecked exception which is thrown to indicate that an index
of some sort (such as to an array, to a string, or to a vector) is out
of range.e.g using List.
as shown in the Documentation
List<String> ls=new ArrayList<>();
ls.add("a");
ls.add("b");
ls.get(3); // will throw IndexOutOfBoundsException , list length is 2
Prevention :
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
Class Constructor usage with index or string message
public IndexOutOfBoundsException() {
super();
}
public IndexOutOfBoundsException(String s) {
super(s);
}
Which are other variations/sub-classes of IndexOutOfBoundsException?
ArrayIndexOutOfBoundsException : This indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array for e.g
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
Prevention :
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 : This is thrown by String methods to indicate that an index is either negative or greater than the size of the string. For some methods such as the charAt method, this exception also is thrown when the index is equal to the size of the string.
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
Prevention :
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
Note: length()
is a function of String
class and length
is a associative field of an array
.
Why these exception occur?
- Usage of Negative index with
arrays
orcharAt
,substring
functions - BeginIndex is less than
0
or endIndex is greater than the length of input string to createsubstring
or beginIndex is larger than the endIndex - When
endIndex - beginIndex
result is less than0
- When input string/array is empty
INFO : It is job of JVM to create the object of appropriate exception and pass it to the place of , where it occurred using throw
keyword like or you can also do it manually using throw
keyword too.
if (s == null) {
throw new IndexOutOfBoundsException("null");
}
How can I fix this ?
- Analyzing StackTrace
- Validating input string against nullity , length or valid indexes
- Using Debugging or Logs
- Using Generic Exception catch block
1.) Analyzing StackTrace
As shown at the beginning of this post , stacktrace provides the necessary information in the initial messages about where it happen , why it happen so you can simply trace that code and apply the required solution .
for e.g the reason StringIndexOutOfBoundsException
and then look for your package name indicating your class file
then go to that line and keeping the reason in mind , simply apply the solution
It's a head start if you study about the exception and its cause as well in documentation.
2.) Validating input string against nullity , length or valid indexes
In case of uncertainty when you don't know about the actual input like response is coming from server (or maybe it's an error or nothing) or user then it's always better to cover all the unexpected cases though believe me few users always like to push the limits of testing so use input!=null && input.length()>0
or for indexes, you can use the ternary operator or if-else
boundary check conditions
3.) Using Debugging or Logs
You can test the running environment of your project in debug mode by adding break-points in your project and system will stop there to wait for your next action and meanwhile you can look into the values of variables and other details.
Logs are just like check-points so when your control cross this point they generate details , basically they are informative messages given by wither system or user can also put logging messages using either Logs or Println messages
4.) Using Generic Exception catch block
Try-catch
blocks are always useful to handle RuntimeExceptions
so you can use multiple catch
block along to handle your possible issues and to give appropriate details
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 ");
}
Further References
What is a NullPointerException, and how do I fix it?
How to solve StringIndexOutOfBoundsException in my case?
The problem might be the lines with selectedHeightValue.substring(...)
To solve it, first of all as a general rumb of thumb, before doing any operation with substring, you should check selectedHeightValue must be valid (so not NULL and not EMPTY).
And then make sure your string size
is enough to make a substring of it (so that it does not exceed its size when you try to access a position in the string that doesn't exist).
Exmple
: the string "ABC" has size 3. And have positions: 0,1,2. If you try to access the string "ABC" in position 3 and up (4,5,6...) than I guess is gonna throw an error because you want to access something that doesn't exist.
How to fix Exception in thread main java.lang.StringIndexOutOfBoundsException: String index out of range: 5 problem in Java
There are two problems with the code. First, you should compare String
s using equals
, not ==
. Otherwise it can return false even for identical String
s.
Second, nextLine
will read from the Scanner
up until after the next newline. But nextInt
only will read up until before that newline, so your first call to nextLine
simply advances the Scanner
by one character and returns an empty String
. You need to call an extra nextLine
after nextInt
to advance onto the next line after your integer. For more information, see this question.
So you should make the following changes to your code:
Scanner scanner = new Scanner(new File("submit.txt"));
int trials = scanner.nextInt();
scanner.nextLine(); //Add this line, to consume the newline character after "5"
// alternatively, you could replace both of the above lines with this:
// int trials = Integer.parseInt(scanner.nextLine());
int total = 0;
for(int x = 0; x <= trials; x++){
String sub = scanner.nextLine();
sub = sub.toLowerCase();
if(sub.substring(0,5).equals("today")) //compare strings using equals, not ==
System.out.println("VALID ENTRY");
else
System.out.println("INCORRECT FORMATTING, TRY ANOTHER SUBMISSION");
}
How to fix StringIndexOutOfBoundsException error?
as mentioned above there are some compile-errors (try to use an IDE, that helps).
After cleaning those up, I made some changes and it should work:
String str1 = "abcdef";
String str2 = "abcgef";
String com = "";
String com2 = "";
int a;
int b;
for (int i = 0; i < str1.length(); i++) {
//counts removed (never used)
for (int j = 0; j < str2.length(); j++) {
a = i;
b = j;
com2 = ""; // Reset before start a new Check Loop
while (str1.charAt(a) == str2.charAt(b)) {
com2 = com2 + str1.charAt(a);
if (com2.length() > com.length()) {
com = com2;
}
/**
* length() goes from 0 (empty String) to n
* index 0 is the first char in that String
* so you need to adjust that (the simple way is -1)
*/
if(a < str1.length()-1) {
a++;
}
if(b < str2.length()-1) {
b++;
}
//check for end of String -> Exit loop
if(a >= str1.length()-1 && b >= str2.length()-1) {
break;
}
}
}
}
System.out.println(com);
}
StringIndexOutOfBoundsException String index out of range: 0
The problem occurs when line
is empty (e.g. ""
). Then it doesn't have a character at index 0, hence your error.
To fix, you can check the length of line
before you use charAt
:
System.out.println(line);
char x;
if (line.length() < 1) {
System.out.println("next line is empty");
} else {
x = line.charAt(0);
while((line.charAt(0)!='/')&&(Character.isWhitespace(x)==false))
{
line = inputFile.nextLine();
if (line.length() < 1) {
System.out.println("next line is empty");
break;
}
x = line.charAt(0);
System.out.println(line);
System.out.println(x);
}
}
Related Topics
What Are the Pros and Cons of the Leading Java HTML Parsers
How to Write Files to External Public Storage in Android So That They Are Visible from Windows
Showing Firebase Data in Listview
Java Using Much More Memory Than Heap Size (Or Size Correctly Docker Memory Limit)
How to Write a Correct Micro-Benchmark in Java
What Does the 'Static' Keyword Do in a Class
How to Deal With "Java.Lang.Outofmemoryerror: Java Heap Space" Error
How to Read a Large Text File Line by Line Using Java
Why Don't Java Generics Support Primitive Types
Converting HTML to Pdf Using Itext
How to Use Java 8 For Android Development
How to Declare a Variable in Gradle Usable in Java
Error: Could Not Find or Load Main Class
What Does a "Cannot Find Symbol" or "Cannot Resolve Symbol" Error Mean
Java Inner Class and Static Nested Class
Including All the Jars in a Directory Within the Java Classpath