Tôi biết chủ đề này là khá cũ nhưng đây là một vấn đề cơ bản mà tôi nghĩ rằng nó đảm bảo làm rõ.
Câu hỏi đặt đúng vị trí. Tôi xem đây là lỗi phần mềm trong phương thức Java String.substring (int beginIndex, int endIndex).
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring%28int,%20int%29.
Từ Java Documents https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
Java/C/C++ và mọi ngôn ngữ khác mà tôi biết KHÔNG xem các chỉ số mảng như là 'chia' giữa các phần tử mảng.
Tham số: beginIndex - chỉ mục bắt đầu, bao gồm. endIndex - chỉ mục kết thúc, độc quyền.
Hoặc là endIndex bị đặt tên sai vì ngôn ngữ không cho phép truy cập bộ nhớ vào địa chỉ ở endIndex + 1 được yêu cầu bao gồm phần tử mảng cuối HOẶC endIndex bị định nghĩa sai và phải là: endIndex - chỉ mục kết thúc, bao gồm .
Trường hợp nhiều khả năng nhất là thông số thứ hai bị đặt tên sai. Nó phải là: chiều dài - độ dài của chuỗi bắt đầu mong muốn tại beginIndex.
Chúng tôi biết rằng Gosling dựa trên cú pháp Java trên ngôn ngữ C/C++ để làm quen. Từ lớp C + + + http://www.cplusplus.com/reference/string/string/substr/, chúng tôi thấy định nghĩa phương thức là:
chất nền chuỗi (size_t pos = 0, size_t len = npos) const;
Lưu ý rằng tham số thứ hai trong định nghĩa phương thức là 'len' cho chiều dài.
len Số ký tự để bao gồm trong chuỗi con (nếu chuỗi ngắn hơn, nhiều ký tự nhất có thể được sử dụng).
testString có 10 ký tự, vị trí chỉ mục từ 0 đến 9. Chỉ định endIndex là 10 nên luôn ném chỉ mục IndexOutOfBoundsException() vì testString không có endIndex là 10.
Nếu chúng tôi thử nghiệm phương pháp này trong JUnit với các giá trị cụ thể xem xét phương pháp C++, chúng tôi mong đợi:
Chuỗi testString = "testString"; assertThat (testString.substring (4, 6), equalTo ("String"));
nhưng tất nhiên chúng tôi được dự kiến: "String" nhưng là "St"
Chiều dài của testString từ chỉ số từ 0 đến char 'g' trong 'String' là 10 ký tự. Nếu chúng tôi sử dụng 10 làm thông số 'endIndex',
Chuỗi testString = "testString"; assertThat (testString.substring (4, 10), equalTo ("String"));
"Vượt qua" từ JUnit.
Nếu đổi tên tham số 2 thành "lengthOfSubstringFromIndex0", bạn không phải thực hiện đếm endIndex - 1 và nó không bao giờ ném chỉ số IndexOutOfBoundsException() được mong đợi khi chỉ định một endIndex, 10, nằm ngoài phạm vi cho mảng cơ bản. http://docs.oracle.com/javase/7/docs/api/java/lang/IndexOutOfBoundsException.html
Đây chỉ là một trong những thời điểm mà bạn phải nhớ sự riêng tư của phương pháp này. Tham số thứ hai không được đặt tên chính xác. Chữ ký của phương thức Java phải là:
public String substring(int beginIndex,
int lengthOfSubstringFromIndex0)
Hoặc phương pháp được xác định lại để khớp với chuỗi C++ :: phương thức substr. Việc định nghĩa lại tất nhiên sẽ có nghĩa là viết lại toàn bộ internet, vì vậy nó không có khả năng.
Ahh! cảm ơn những người đầu, tôi đã nhìn vào cùng một trang tài liệu nhưng không biết tôi đã phải cuộn xuống tất cả các cách để có thêm chi tiết ... –
Chúc các javadoc có thể có một lưu ý về điều này, hoặc những kẻ bất cẩn như tôi sẽ mong đợi 'IndexOutOfBoundsException' xảy ra nếu beginIndex = String.length(). –