Java-subtekenreeks: ‘tekenreeksindex buiten bereik’

Ik vermoed dat ik deze fout krijg omdat de tekenreeks een null-waarde probeert te subtekenen. Maar zou het deel ".length() > 0"dat probleem niet oplossen?

Hier is het Java-fragment:

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

Ik krijg deze fout:

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)

Antwoord 1, autoriteit 100%

Ik vermoed dat ik deze foutmelding krijg
omdat de string probeert
subtekenreeks een Null-waarde. Maar zou niet
het “.length() > 0” gedeelte elimineert
dat probleem?

Nee, het aanroepen van itemdescription.length() wanneer itemdescription null is, zou geen StringIndexOutOfBoundsException genereren, maar eerder een NullPointerException, aangezien je in wezen zou proberen een methode aan te roepen op null.

Zoals anderen al hebben aangegeven, geeft StringIndexOutOfBoundsException aan dat de itembeschrijving niet ten minste 38 tekens lang is. U wilt waarschijnlijk met beide voorwaarden omgaan (ik neem aan dat u wilt afkappen):

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);

Misschien een goede plek voor een hulpprogramma als je dat veel doet…


Antwoord 2, autoriteit 99%

Het is jammer dat substringniet is geïmplementeerd op een manier die korte strings verwerkt – zoals in andere talen, b.v. Python.

Ok, we kunnen dat niet veranderen en moeten elke keer dat we substrgebruiken deze edge-case in overweging nemen, in plaats van if-else-clausules zou ik voor deze kortere variant gaan:

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

Antwoord 3, autoriteit 28%

Ik zou apache commons langaanraden. Een oneliner lost het probleem op.

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

Antwoord 4, autoriteit 28%

Je moet echt controleren of de lengte van de string groter of gelijk is aan 38.


Antwoord 5, autoriteit 17%

substring(0,38)betekent dat de string 38 tekens of langer moet zijn. Zo niet, dan is de “String index buiten bereik”.


Antwoord 6, autoriteit 14%

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

Antwoord 7, autoriteit 14%

Java’s substring-methode mislukt wanneer je een substring probeert te krijgen die begint bij een index die langer is dan de string.

Een eenvoudig alternatief is om 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

Let op, als je Apache Commons lib om de een of andere reden niet kunt gebruiken, kun je gewoon pak de onderdelen die je nodig hebt bij de bron

// 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);
}

Antwoord 8, autoriteit 6%

Ik neem aan dat uw kolom 38 tekens lang is, dus u wilt afkappenitemdescriptionom in de database te passen. Een hulpprogramma als de volgende zou moeten doen wat u wilt:

/**
 * 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()));
}

dan noem je het gewoon zo:

String value = "_";
if (itemdescription != null && itemdescription.length() > 0) {
  value = truncate(itemdescription, 38);
}
pstmt2.setString(3, value);

Antwoord 9, autoriteit 6%

itemdescriptionis korter dan 38 tekens. Dat is de reden waarom de StringOutOfBoundsExceptionwordt gegenereerd.

Controleren van .length() > 0zorgt er gewoon voor dat de Stringeen niet-null-waarde heeft, wat je moet doen is controleren of de lengte lang genoeg is. Je zou kunnen proberen:

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

10

Wanneer dit passend is, gebruik ik overeenkomsten in plaats van substring .

Met substring :

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

Met Matches (MOET gebruiken REGEX NOTATIE):

if( myString.matches("Someting I expect.*") ) {
    // Do stuff
}
// This works with all strings

11

Moet iemand hetzelfde probleem voorstellen.

Doe dit:
str.substring (… (trim ());

Ik hoop dat het sneltjes helpt 😎


12

U krijgt dit als itemdescriptie korter is dan 38 tekens

U kunt eruit zien welke uitzonderingen worden gegooid en wanneer in de Java-API
In uw zaak voor String # Substring (INT, INT): https://docs.oracle.com/javase/9/docs/api/java/lang/string.html#substring-int-int-

Substring 
openbare string substring (int beginindex, int endindex) 
  . . .
worpen: 
 Indexoutofboundsexception 
 Als de beginindex negatief is,
 of Endindex is groter dan de lengte van dit string-object ,
 of beginnendex is groter dan endindex.
(Hetzelfde geldt ook voor eerdere Java-versies)

Other episodes