#java
Вопрос:
Когда я тестировал какой-то код, я заметил, что метод подстроки не создавал бы исключения, если бы индекс, который я использовал, был равен длине строки. Например:
String s = "holy";
System.out.println(s.substring(4));
Вывод ничего не вернет, но не вызовет исключения. Но если бы я попытался позвонить:
String s = "holy";
System.out.println(s.substring(5));
Это вызовет исключение IndexOutOfBoundsException. Я прочитал Javadoc для этого метода, и в нем говорится
если beginIndex отрицателен или больше длины этого строкового объекта.
Кто-нибудь знает, почему это позволяет, чтобы начальный индекс был равен длине строки?
Ответ №1:
Подумайте о других призывах substring
:
"holy".substring(n)
может быть визуализировано как копирование диапазона символов между n
(включительно) и концом строки (эксклюзивно).
Например:
"holy".substring(0)`
h o l y
O-------X (O = start, X = end)
0 1 2 3 4
То есть начальная позиция находится непосредственно перед символом, а конечная позиция-сразу после символа. Результирующая длина строки end - start
в данном случае равна 4.
и
"holy".substring(1)
h o l y
O-----X // length = 4 - 1 = 3.
0 1 2 3 4
и т.д. Затем:
"holy".substring(4)
может быть визуализирован как
h o l y
O // O and X are at the same position
X // length = 4 - 4 = 0
0 1 2 3 4
Хорошо, что O и X находятся в одной и той же позиции: это просто означает, что результатом является строка нулевой длины, ""
.
Но увеличьте индекс до 5:
"holy".substring(5)
h o l y
X-O // O is after X
// length = 4 - 5 = -1 (?!)
0 1 2 3 4 5
Строка длиной -1 не имеет смысла, отсюда и исключение.
Комментарии:
1. Спасибо, визуализация очень помогла, и теперь это имеет смысл
Ответ №2:
- общедоступная строковая подстрока(int startIndex) возвращает подстроку из начального индекса вашей строки. Таким образом, в вашем примере это будет позиция 4 (которая существует), а подстрока будет «» (пустая строка).
Комментарии:
1. Что на самом деле происходит «под капотом»? Позиция 4 технически находится за пределами диапазона индексов строки, так как же можно что-то вернуть, не выдав ошибку?
Ответ №3:
В принципе, для этого есть одна причина substring(int beginIndex, int endIndex)
, если в beginIndex == endIndex
результате получается пустая строка. Таким образом, учитывая это свойство и тот факт, что максимальное значение endIndex
равно длине строки, то разрешение string.substring(string.length(), string.length())
должно быть разрешено и также возвращать пустую строку. И это последнее можно упростить до string.substring(string.length())
.
Разрешение длины в качестве допустимого начального индекса также обеспечивает ряд приятных свойств:
"".substring(0)
ВОЗВРАТ""
- Рассматривая пары
String start = string.substring(0, n)
иString end = string.substring(n)
результаты в следующем:n = 0
:start = ""
,end = string
n = string.length()
:start = string
,end = ""
Запрещение этого и создание исключения потребовало бы всех видов дополнительных проверок границ в коде обработки строк (и в самой подстроке, если на то пошло).