2009-06-04 10 views
14

Zgaduję, że dostaję ten błąd, ponieważ ciąg próbuje podciąć wartość null. Ale czy część ".length() > 0" nie wyeliminuje tego problemu?Podłańcuch języka Java: 'indeks ciągu poza zakresem'

Oto Java snippet:

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

mam ten błąd:

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) 

Odpowiedz

28

I"m guessing i'm getting this error because the string is trying to substring a Null value. But wouldn't the ".length() > 0" part eliminate that issue?

Nie, nazywając itemdescription.length(), gdy itemdescription jest null nie generują StringIndexOutOfBoundsException, ale raczej NullPointerException ponieważ można byłoby w istocie próbuje wywołać metodę na null.

Jak wskazali inni, wyjątek StringIndexOutOfBoundsException wskazuje, że opis pozycji nie ma co najmniej 38 znaków. Prawdopodobnie chcesz obsługiwać oba warunki (I zakładając, że chcesz obciąć):

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

Może być dobrym miejscem dla funkcji użytkowej, jeśli robisz dużo ...

9

Naprawdę trzeba sprawdzić, czy długości struny jest większa lub równa 38.

4

substring(0,38) oznacza, że ​​ciąg musi mieć 38 znaków lub więcej. Jeśli nie, "Indeks struny jest poza zakresem".

1

itemdescription jest krótszy niż 38 znaków. Właśnie dlatego wyrzucany jest StringOutOfBoundsException.

Po sprawdzeniu, czy .length() > 0 po prostu upewnia się, że String ma pewną nie-pustą wartość, należy sprawdzić, czy długość jest wystarczająco długa. Można spróbować:

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

Byłbym naprawdę zainteresowany tym, co zwróci itemdescription.substring (0, item opis.length()) :) – pugmarx

+0

var itemdescription = new String ("Hello, World!"); alert (itemdescription.substring (0, item opis.length)); zwraca "Hello, World!". – tom

+0

Prawdopodobnie chciał coś z tym zrobić. –

2

Ja zakładając, że kolumna ma 38 znaków długości, więc chcesz skrócićitemdescription, aby zmieścić się w bazie danych. Funkcja Narzędzie jak poniżej powinien robić to, co chcesz:

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

potem po prostu nazwać tak:

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

pstmt2.setString(3, value); 
5

Polecam apache commons lang. Jeden liner zajmuje się problemem.

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

Szkoda że substring nie jest realizowane w sposób, który obsługuje krótkie ciągi - podobnie jak w innych językach np Pyton.

Ok, nie możemy tego zmienić i trzeba rozważyć tym przypadku krawędź każdym razem używamy substr zamiast if-else klauzule pójdę do tego krótszego wariantu:

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

substring metoda Java nie powiedzie się, gdy cię spróbuj uzyskać podciąg rozpoczynający się od indeksu dłuższego niż ciąg.

Prostym rozwiązaniem jest użycie 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 
0

Musisz sprawdzić długość ciągu. Zakładasz, że możesz zrobić substring(0,38) tak długo, jak String nie jest null, ale faktycznie potrzebujesz, aby ciąg miał przynajmniej 38 znaków długości.