32

文字列が値をサブストリングしようとしているため、このエラーが発生していると思い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)
4

13 に答える 13

56

substringPythonなどの他の言語のように、短い文字列を処理する方法で実装されていないのは残念です。

わかりました。これを変更することはできず、使用するたびにこのエッジケースを考慮する必要がありsubstrます。if-else句の代わりに、この短いバリアントを使用します。

myText.substring(0, Math.min(6, myText.length()))
于 2014-03-12T12:18:53.547 に答える
36

文字列がNull値をサブストリングしようとしているため、このエラーが発生していると思います。しかし、「。length()> 0」の部分でこの問題が解消されるのではないでしょうか?

いいえ、itemdescriptionがnullのときにitemdescription.length()を呼び出すと、StringIndexOutOfBoundsExceptionは生成されませんが、本質的にnullでメソッドを呼び出そうとするため、NullPointerExceptionが生成されます。

他の人が示しているように、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);

あなたがそれをたくさんするなら、ユーティリティ関数のための良い場所かもしれません...

于 2009-06-04T23:17:01.197 に答える
11

apachecommonslangをお勧めします。ワンライナーが問題を処理します。

pstmt2.setString(3, StringUtils.defaultIfEmpty(
    StringUtils.subString(itemdescription,0, 38), "_")); 
于 2009-06-05T11:46:13.787 に答える
10

文字列の長さが38以上かどうかを実際に確認する必要があります。

于 2009-06-04T22:55:34.517 に答える
7

substring文字列よりも長いインデックスで始まる部分文字列を取得しようとすると、Javaのメソッドは失敗します。

簡単な代替手段は、ApacheCommonsStringUtils.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

何らかの理由でApacheCommonslibを使用できない場合は、ソースから必要な部分を取得するだけでよいことに注意してください。

// 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);
}
于 2016-08-17T19:14:38.150 に答える
6

substring(0,38)文字列は38文字以上である必要があることを意味します。そうでない場合は、「文字列インデックスが範囲外です」。

于 2009-06-04T22:56:41.953 に答える
5
if (itemdescription != null && itemdescription.length() > 0) {
    pstmt2.setString(3, itemdescription.substring(0, Math.min(itemdescription.length(), 38))); 
} else { 
    pstmt2.setString(3, "_"); 
}
于 2009-06-04T22:58:25.163 に答える
2

itemdescription38文字より短いです。StringOutOfBoundsExceptionがスローされているのはそのためです。

チェック.length() > 0するだけStringで、にnull以外の値があることを確認します。必要なのは、長さが十分に長いことを確認することです。あなたは試すことができます:

if(itemdescription.length() > 38)
  ...
于 2009-06-04T22:58:04.730 に答える
2

列の長さが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);
于 2009-06-04T23:37:29.937 に答える
0

文字列の長さを確認する必要があります。substring(0,38)文字列がでない限り実行できると想定しますがnull、実際には文字列の長さが38文字以上である必要があります。

于 2016-08-17T19:20:03.163 に答える
0

これが適切な場合、私は部分文字列の代わりに一致を使用します。

部分文字列付き

if( myString.substring(1,17).equals("Someting I expect") ) {
    // Do stuff
}
// Does NOT work if myString is too short

一致する場合(正規表現表記を使用する必要があります):

if( myString.matches("Someting I expect.*") ) {
    // Do stuff
}
// This works with all strings
于 2019-04-25T21:25:35.560 に答える
0

誰かが同じ問題に直面した場合。

これを行う:str.substring(...(trim());

それが誰かを助けることを願っています

于 2020-10-11T08:37:54.567 に答える
-1

itemdescriptionが38文字より短い場合にこれを取得します

String#substring(int、int)の場合、どの例外がスローされ、いつJAVA APIにあるかを確認できます:https://docs.oracle.com/javase/9​​/docs/api/java/lang/String。 html#substring-int-int-

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

スロー:
 IndexOutOfBoundsException
 beginIndexが負の場合、
 またはendIndexがこのStringオブジェクトの長さよりも大きい、
 またはbeginIndexがendIndexよりも大きい。



(以前のJavaバージョンにも同じことが当てはまります)
于 2018-06-13T09:19:00.370 に答える