There is a method on String class that has the signature:
if you use it like: "hamburger".substring(4, 8) it returns "urge" 'h' 'a' 'm' 'b' 'u' 'r' 'g' 'e' 'r' 0 1 2 3 4 5 6 7 8 so it starts at position 4 and ends at position 7, not 8, so the second parameter is 1-based and the first parameter is 0-based. This is specified in the javadoc, but i don't understand why they take such a decision!
It's probably a matter of computational efficiency. The start position plus substring length is exactly the value you have to enter in the "end position" parameter. Saves an operation (add or subtracting one).
Must admit, I've always felt the 2nd argument to the substring method was a little odd. I also hate having to remember and think about the 2nd argument based on 1 as the starting index position rather than zero.
So I've found it easier to remember the substring method's 2nd argument as "up to but NOT INCLUDING the endIndex position". Then in "my world" I'm happy because everything from arrays, substrings etc still start at index position zero.
This is a common pattern in Java and many other programming languages; I believe it starts from the way we use arrays:
The array starts at index 0, which is used, but the last element of the array that's accessed is at index array.length - 1. The "end" at index array.length is not included. Methods like substring() just mimic this pattern, because they assume it should be ingrained into most programmers. There are a few places in Java which do not follow this pattern, and they are (for me at least) more bug-prone. E.g. in a ResultSet, all the getXXX() methods use a columnIndex that starts at 1, not 0. Annoying when you're used to starting at 0. [ April 18, 2007: Message edited by: Jim Yingst ]