So che questo thread è piuttosto vecchio, ma questo è un problema fondamentale che penso giustifichi un chiarimento.
La domanda è corretta. Lo vedo come un errore del software nel metodo Java String.substring (int beginIndex, int endIndex).
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring%28int,%20int%29.
Dal Java Docs https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html

Java/C/C++ e di ogni altra lingua che io sappia non considera l'indice dell'array come il 'divisorio' tra gli elementi dell'array.
Parametri: beginIndex - l'indice iniziale, incluso. endIndex - l'indice finale, esclusivo.
O endIndex è misnamed perché la lingua non consente l'accesso di memoria a un indirizzo al endIndex + 1 che è necessario includere l'ultimo elemento dell'array O endIndex è mis-definiti da: endIndex - l'indice finale, compreso .
Il caso più probabile è che il secondo parametro sia stato erroneamente denominato. Dovrebbe essere: lunghezza: la lunghezza della stringa desiderata inizia da beginIndex.
Sappiamo che Gosling ha basato la sintassi Java sui linguaggi C/C++ per familiarità. Dalla classe di stringhe C+++ http://www.cplusplus.com/reference/string/string/substr/ vediamo che la definizione del metodo è:
substr string (size_t pos = 0, size_t len = npos) const;
Si noti che il secondo parametro nella definizione del metodo è 'len' per la lunghezza.
len Numero di caratteri da includere nella sottostringa (se la stringa è più breve, come numero possibile di caratteri vengono utilizzati).
testString ha 10 caratteri, posizioni di indice 0 a 9. Specifica di un endIndex di 10 dovrebbe sempre gettare l'IndexOutOfBoundsException() perché testString ha endIndex di 10.
Se testiamo il metodo in JUnit con valori concreti guardando il metodo C++, ci aspettiamo:
String testString = "testString"; assertThat (testString.substring (4, 6), equalTo ("String"));
ma naturalmente otteniamo previsto: "Stringa", ma era "St"
La lunghezza del testString dall'indice 0 a char 'g' a 'String' è di 10 caratteri. Se si utilizza 10 come parametro 'endIndex',
String testString = "testString"; assertThat (testString.substring (4, 10), equalTo ("String"));
"Pass" da JUnit.
Se rinominiamo il parametro 2 in "lengthOfSubstringFromIndex0" non è necessario eseguire il conteggio endIndex - 1 e non getta mai IndexOutOfBoundsException() che è previsto quando si specifica un endIndex, 10, che è fuori intervallo per l'array sottostante. http://docs.oracle.com/javase/7/docs/api/java/lang/IndexOutOfBoundsException.html
Questa è solo una di quelle volte che devi ricordare l'idiosincrasia di questo metodo. Il secondo parametro non è denominato correttamente. La firma del metodo Java dovrebbe essere:
public String substring(int beginIndex,
int lengthOfSubstringFromIndex0)
o il metodo ridefinito in modo che corrisponda C++ metodo stringa :: substr. Ridefinire ovviamente significherebbe riscrivere l'intero internet, quindi non è probabile.
Ahh! grazie per il tip, stavo guardando la stessa pagina doc ma non sapevo che dovevo scorrere fino in fondo per ottenere maggiori dettagli ... –
Vorrei che il javadoc possa avere una nota su questo, o ragazzi disattenti come me aspettarsi 'IndexOutOfBoundsException' se initIndex = String.length(). –