Вопрос

Я предполагаю, что я получаю эту ошибку, потому что строка пытается подстроить a 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)
Это было полезно?

Решение

Я предполагаю, что получаю эту ошибку потому что строка пытается подстроить нулевое значение.Но разве часть ".length() > 0" не устранила бы эту проблему?

Нет, вызываю itemdescription.length(), когда itemdescription равно null, не будет генерировать исключение StringIndexOutOfBoundsException, а скорее исключение NullPointerException, поскольку вы, по сути, пытаетесь вызвать метод на ноль.

Как указывали другие, исключение StringIndexOutOfBoundsException указывает, что длина описания элемента не превышает 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);

Может быть, это хорошее место для служебной функции, если вы часто этим занимаетесь...

Другие советы

Очень жаль , что substring не реализован таким образом, чтобы обрабатывать короткие строки – как в других языках, напримерПитон.

Хорошо, мы не можем это изменить и должны учитывать этот крайний случай каждый раз, когда мы используем substr, вместо предложений if-else я бы выбрал этот более короткий вариант:

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

Вам действительно нужно проверить, больше ли длина строки или равна 38.

Я бы порекомендовал общий язык apache lang.Однострочник решает проблему.

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

substring(0,38) означает, что Строка должна состоять из 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);

Java-х substring метод завершается с ошибкой при попытке получить подстроку, начинающуюся с индекса, который длиннее строки.

Простой альтернативой является использование Общее достояние Apache 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

Обратите внимание, если вы по какой-то причине не можете использовать 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);
}

itemdescription короче 38 символов.Именно поэтому StringOutOfBoundsException бросается.

Проверка .length() > 0 просто удостоверяется, что String имеет некоторое ненулевое значение, все, что вам нужно сделать, это проверить, что длина достаточно велика.Вы могли бы попробовать:

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

Вы должны проверить длину строки.Вы предполагаете, что можете сделать substring(0,38) до тех пор, пока Строка не null, но на самом деле вам нужно, чтобы длина строки составляла не менее 38 символов.

Когда это уместно, я использую Матчи вместо того , чтобы подстрока.

С подстрока:

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

Вы получите это, если описание элемента короче 38 символов

Вы можете посмотреть, какие исключения генерируются и когда в JAVA API в вашем случае для String#substring(int,int): https://docs.oracle.com/javase/9/docs/api/java/lang/String.html#substring-int-int-

подстрока
общедоступная строковая подстрока (int beginIndex, int endIndex)
   . . .

Бросает:
 Исключение IndexOutOfBoundsException
 if the beginIndex is negative,
 or endIndex больше, чем длина этого строкового объекта, 
 or beginIndex is larger than endIndex.



(same applies to previous java versions as well)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top