JDK-4515147 : (str) String.substring(start, end) failure could provide better detail message
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.4.0,1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • Submitted: 2001-10-16
  • Updated: 2017-05-04
  • Resolved: 2017-05-04
Description
Name: nt126004			Date: 10/16/2001


java version "1.4.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta2-b77)
Java HotSpot(TM) Client VM (build 1.4.0-beta2-b77, mixed mode)

Note that this is also a problem in 1.3 and probably earlier.

Short test program:

public class Test
{
    public static void main (String [] args)
        throws Exception
    {
        String s = "Hello";
        
        s.substring (4, 1);
    }
}

I would expect this to give an IndexOutOfBoundsException, which it does.
Unfortunately, the message is far from helpful:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: -3
        at java.lang.String.substring(String.java:1443)
        at Test.main(Test.java:8)

The index -3 is never used, and I can't easily think of any substring
algorithm which *would* end up using it.

I would suggest that IllegalArgumentException should be used rather than an
IndexOutOfBoundsException, as that's more descriptive. Failing that, a better
error message should be used.
(Review ID: 133804) 
======================================================================

Name: rmT116609			Date: 08/12/2004


A DESCRIPTION OF THE REQUEST :
Currently if the method substring(start, end) is called on an instance of String, and start is greater than end, then the exception thrown by the method is a StringIndexOutOfBoundsException with an out of bounds value of (end - start).

For debugging issues this is confusing, for it semantically would imply that either of the end points is out of bounds, not that there is something wrong with the range definition.

It would be more informative if the exception thrown implied there was a problem with the range -- at least something informative in the message string of the exception.


JUSTIFICATION :
More informative exceptions == good for debugging.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: Start index of 5 is greater than end index of 3
        at java.lang.String.substring(Unknown Source)
        at StringSubstringBlah.main(StringSubstringBlah.java:5)

ACTUAL -
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -2
        at java.lang.String.substring(Unknown Source)
        at StringSubstringBlah.main(StringSubstringBlah.java:5)


---------- BEGIN SOURCE ----------
public class StringSubstringBlah {

	static public void main (String[] args) {
		String str = "This is a string";
		String substr = str.substring(5, 3);
	}

}

---------- END SOURCE ----------
(Review ID: 296465)
======================================================================

Comments
The index checking for String was retooled in JDK 9. The message emitted by the submitted code fragment is now: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin 4, end 1, length 5 at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3121) at java.base/java.lang.String.substring(String.java:1911) at other.Str.main(Str.java:27) Closing as Not an Issue.
04-05-2017

WORK AROUND Name: nt126004 Date: 10/16/2001 Customer Workaround: When you get this error, read the source of java.lang.String to work out why such a bizarre message is being given... ======================================================================
13-08-2004

EVALUATION The index -3 refers to the difference between the difference between the end and start index (1 - 4 = -3). $ jdk118; java Test java.lang.StringIndexOutOfBoundsException: String index out of range: -3 at java.lang.String.substring(String.java) at Test.main(Test.java:8) $ jdk122; java Test Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -3 at java.lang.String.substring(String.java, Compiled Code) at Test.main(Test.java, Compiled Code) $ jdk131; java Test Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -3 at java.lang.String.substring(String.java:1525) at Test.main(Test.java:8) $ jdk14; java Test Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -3 at java.lang.String.substring(String.java:1449) at Test.main(Test.java:8) While an IllegalArgumentException is probably more applicable in this case, the API for this method very clearly states that an IndexOutOfBoundsException should be thrown. Changing this behaviour after so much time is inadvisable. There are two possible solutions to provide the user with better information. We could construct an appropriate detail message (as a String) at the time the exception is created. Alternatively, we could add a new constructor StringIndexOutOfBoundsException(int start, int end) which provides an appropriate description of the problem. The later solution is perferred. -- iag@sfbay 2001-10-16
16-10-2001