Java子字符串:'字符串索引超出范围'

phi*_*ill 20 java substring indexoutofboundsexception

我猜我得到了这个错误,因为字符串试图对一个null值进行子串.但这".length() > 0"部分不会消除这个问题吗?

这是Java片段:

if (itemdescription.length() > 0) {
    pstmt2.setString(3, itemdescription.substring(0,38));
} 
else { 
    pstmt2.setString(3, "_");
} 
Run Code Online (Sandbox Code Playgroud)

我收到了这个错误:

 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)
Run Code Online (Sandbox Code Playgroud)

Ber*_*t F 33

我猜测我得到了这个错误,因为字符串试图将Null值子串起来.但是".length()> 0"部分不会消除这个问题吗?

不,当itemdescription为null时调用itemdescription.length()不会生成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);
Run Code Online (Sandbox Code Playgroud)

如果你这么做的话,可能是实用功能的好地方......


lin*_*nqu 26

很遗憾substring没有以处理短字符串的方式实现 - 就像在其他语言中一样,例如Python.

好的,我们无法改变这一点,每次使用时都必须考虑这个边缘情况substr,而不是if-else子句我会选择这个较短的变体:

myText.substring(0, Math.min(6, myText.length()))
Run Code Online (Sandbox Code Playgroud)

  • 是的,这太荒谬了。 (5认同)

Jas*_*son 9

你真的需要检查字符串的长度是否大于或等于38.


H M*_*les 7

我会推荐apache commons lang.单线程可以解决问题.

pstmt2.setString(3, StringUtils.defaultIfEmpty(
    StringUtils.subString(itemdescription,0, 38), "_")); 
Run Code Online (Sandbox Code Playgroud)


Apo*_*isp 5

substring(0,38)表示字符串必须是38个字符或更长。如果不是,则“字符串索引超出范围”。


Jee*_*Bee 5

if (itemdescription != null && itemdescription.length() > 0) {
    pstmt2.setString(3, itemdescription.substring(0, Math.min(itemdescription.length(), 38))); 
} else { 
    pstmt2.setString(3, "_"); 
}
Run Code Online (Sandbox Code Playgroud)

  • 我真的很想知道itemdescription.substring(0,itemdescription.length())将返回什么:) (2认同)

Bra*_*rks 5

substring当您尝试从比字符串长的索引开始获取子字符串时,Java 的方法失败。

一个简单的替代方法是使用Apache CommonsStringUtils.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
Run Code Online (Sandbox Code Playgroud)

请注意,如果由于某种原因您不能使用 Apache Commons lib,您可以从源代码中获取您需要的部分

// 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);
}
Run Code Online (Sandbox Code Playgroud)