Подстрока Java: "строковый индекс вне диапазона"
Я предполагаю, что получаю эту ошибку, потому что строка пытается подставить null
значение. Но не устранит ли эту проблему часть ".length() > 0"
?
Вот фрагмент кода Java:
if (itemdescription.length() > 0) {
pstmt2.setString(3, itemdescription.substring(0,38));
}
else {
pstmt2.setString(3, "_");
}
Я получил эту ошибку:
java.lang.StringIndexOutOfBoundsException: String index out of range: 38
at java.lang.String.substring(Unknown Source)
at MASInsert2.itemimport(MASInsert2.java:192)
at MASInsert2.processRequest(MASInsert2.java:125)
at MASInsert2.doGet(MASInsert2.java:219)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:627)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:835)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:640)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1286)
at java.lang.Thread.run(Unknown Source)
Ответы
Ответ 1
Я предполагаю, что получаю эту ошибку потому что строка пытается substring a Значение Null. Но не часть ".length() > 0" устраняет эта проблема?
Нет, вызов itemdescription.length(), когда itemdescription равен null, не будет генерировать исключение StringIndexOutOfBoundsException, а скорее исключение NullPointerException, поскольку вы по существу пытаетесь вызвать метод null.
Как указывали другие, StringIndexOutOfBoundsException указывает, что itemdescription не должен содержать не менее 38 символов. Вероятно, вы хотите обрабатывать оба условия (я предполагаю, что вы хотите усечь):
final String value;
if (itemdescription == null || itemdescription.length() <= 0) {
value = "_";
} else if (itemdescription.length() <= 38) {
value = itemdescription;
} else {
value = itemdescription.substring(0, 38);
}
pstmt2.setString(3, value);
Может быть хорошим местом для функции полезности, если вы это сделаете много...
Ответ 2
Жаль, что substring
не реализована так, чтобы обрабатывать короткие строки - как в других языках, например, Python.
Хорошо, мы не можем это изменить и должны рассматривать этот крайний случай каждый раз, когда мы используем substr
, вместо предложений if-else я бы выбрал этот более короткий вариант:
myText.substring(0, Math.min(6, myText.length()))
Ответ 3
Вы действительно должны проверить, является ли длина строки больше или равна 38.
Ответ 4
Я бы порекомендовал apache commons lang. Проблема заключается в том, что один-лайнер заботится о проблеме.
pstmt2.setString(3, StringUtils.defaultIfEmpty(
StringUtils.subString(itemdescription,0, 38), "_"));
Ответ 5
substring(0,38)
означает, что строка должна содержать 38 символов или больше. Если нет, индекс "String" выходит за пределы диапазона.
Ответ 6
if (itemdescription != null && itemdescription.length() > 0) {
pstmt2.setString(3, itemdescription.substring(0, Math.min(itemdescription.length(), 38)));
} else {
pstmt2.setString(3, "_");
}
Ответ 7
Я предполагаю, что ваш столбец длиной 38 символов, поэтому вы хотите усекать itemdescription
, чтобы вписаться в базу данных. Функция полезности, такая как следующая, должна делать то, что вы хотите:
/**
* Truncates s to fit within len. If s is null, null is returned.
**/
public String truncate(String s, int len) {
if (s == null) return null;
return s.substring(0, Math.min(len, s.length()));
}
тогда вы просто вызываете его так:
String value = "_";
if (itemdescription != null && itemdescription.length() > 0) {
value = truncate(itemdescription, 38);
}
pstmt2.setString(3, value);
Ответ 8
Java-метод substring
завершается неудачно, когда вы пытаетесь получить подстроку, начинающуюся с индекса, который длиннее строки.
Простая альтернатива - использовать Apache Commons StringUtils.substring
:
public static String substring(String str, int start)
Gets a substring from the specified String avoiding exceptions.
A negative start position can be used to start n characters from the end of the String.
A null String will return null. An empty ("") String will return "".
StringUtils.substring(null, *) = null
StringUtils.substring("", *) = ""
StringUtils.substring("abc", 0) = "abc"
StringUtils.substring("abc", 2) = "c"
StringUtils.substring("abc", 4) = ""
StringUtils.substring("abc", -2) = "bc"
StringUtils.substring("abc", -4) = "abc"
Parameters:
str - the String to get the substring from, may be null
start - the position to start from, negative means count back from the end of the String by this many characters
Returns:
substring from start position, null if null String input
Обратите внимание: если по какой-то причине вы не можете использовать библиотеку Apache Commons, вы можете просто получить нужные части из исходного кода.
// Substring
//-----------------------------------------------------------------------
/**
* <p>Gets a substring from the specified String avoiding exceptions.</p>
*
* <p>A negative start position can be used to start {@code n}
* characters from the end of the String.</p>
*
* <p>A {@code null} String will return {@code null}.
* An empty ("") String will return "".</p>
*
* <pre>
* StringUtils.substring(null, *) = null
* StringUtils.substring("", *) = ""
* StringUtils.substring("abc", 0) = "abc"
* StringUtils.substring("abc", 2) = "c"
* StringUtils.substring("abc", 4) = ""
* StringUtils.substring("abc", -2) = "bc"
* StringUtils.substring("abc", -4) = "abc"
* </pre>
*
* @param str the String to get the substring from, may be null
* @param start the position to start from, negative means
* count back from the end of the String by this many characters
* @return substring from start position, {@code null} if null String input
*/
public static String substring(final String str, int start) {
if (str == null) {
return null;
}
// handle negatives, which means last n characters
if (start < 0) {
start = str.length() + start; // remember start is negative
}
if (start < 0) {
start = 0;
}
if (start > str.length()) {
return EMPTY;
}
return str.substring(start);
}
Ответ 9
itemdescription
короче 38 символов. Вот почему бросается StringOutOfBoundsException
.
Проверка .length() > 0
просто гарантирует, что значение String
имеет некоторое значение, отличное от нуля, что вам нужно сделать, это проверить, что длина достаточно длинная. Вы можете попробовать:
if(itemdescription.length() > 38)
...
Ответ 10
Вы должны проверить длину строки. Вы предполагаете, что вы можете сделать substring(0,38)
, пока String не является null
, но вам действительно нужна строка длиной не менее 38 символов.
Ответ 11
Когда это уместно, я использую совпадения вместо подстроки.
С подстрокой:
if( myString.substring(1,17).equals("Someting I expect") ) {
// Do stuff
}
// Does NOT work if myString is too short
С совпадениями (необходимо использовать обозначение Regex):
if( myString.matches("Someting I expect.*") ) {
// Do stuff
}
// This works with all strings
Ответ 12
Вы получите это, если itemdescription короче 38 символов
Вы можете посмотреть, какие исключения генерируются и когда в JAVA API в вашем случае для String # substring (int, int): https://docs.oracle.com/javase/9/docs/api/java/lang/String. HTML # подстрока-INT-int-
substring
public String substring(int beginIndex, int endIndex)
. . .
Throws:
IndexOutOfBoundsException
if the beginIndex is negative,
or endIndex is larger than the length of this String object,
or beginIndex is larger than endIndex.
(same applies to previous java versions as well)