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) 

我猜测我得到了这个错误,因为字符串试图将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); 

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

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

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

 myText.substring(0, Math.min(6, myText.length())) 

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

我会推荐apache commons lang 。 单线处理问题。

 pstmt2.setString(3, StringUtils.defaultIfEmpty( StringUtils.subString(itemdescription,0, 38), "_")); 

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

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

我假设您的列长度为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); 

itemdescription短于38个字符。 这就是抛出StringOutOfBoundsException原因。

检查.length() > 0只是确保String有一些非空值,你需要做的是检查长度是否足够长。 你可以尝试:

 if(itemdescription.length() > 38) ... 

当你尝试从一个比字符串更长的索引开始获取子字符串时,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 

您必须检查字符串长度。 假设您可以执行substring(0,38) ,只要String不为null ,但实际上您需要String长度至少为38个字符。

如果itemdescription短于38个字符,则会得到此信息

您可以查看抛出哪些exception以及何时在JAVA API中用于String #substring(int,int): https : //docs.oracle.com/javase/9​​/docs/api/java/lang/String。 HTML#子-INT-内部-

  
 public String substring(int beginIndex,int endIndex)
    。  。  。

 抛出:
  IndexOutOfBoundsExceptionexception
 如果beginIndex为负数,
 或endIndex大于此String对象的长度 , 
 或beginIndex大于endIndex。



 (同样适用于以前的java版本)