Java 为什么是;“超出范围”;不为'抛出;子字符串(起始索引、结束索引)和#x27;
在Java中,我使用的是Java 为什么是;“超出范围”;不为'抛出;子字符串(起始索引、结束索引)和#x27;,java,substring,Java,Substring,在Java中,我使用的是substring()方法,我不确定为什么它没有抛出“索引外”错误 字符串abcde的索引从0到4开始,但是substring()方法将startIndex和endIndex作为参数,因为我可以调用foo.substring(0)并获取“abcde” 那么为什么子字符串(5)起作用呢?该索引应该超出范围。原因是什么 /* 1234 abcde */ String foo = "abcde"; System.out.println(foo.substring(0)); Sy
substring()
方法,我不确定为什么它没有抛出“索引外”错误
字符串abcde
的索引从0到4开始,但是substring()
方法将startIndex和endIndex作为参数,因为我可以调用foo.substring(0)并获取“abcde”
那么为什么子字符串(5)起作用呢?该索引应该超出范围。原因是什么
/*
1234
abcde
*/
String foo = "abcde";
System.out.println(foo.substring(0));
System.out.println(foo.substring(1));
System.out.println(foo.substring(2));
System.out.println(foo.substring(3));
System.out.println(foo.substring(4));
System.out.println(foo.substring(5));
此代码输出:
abcde
bcde
cde
de
e
//foo.substring(5) output nothing here, isn't this out of range?
当我将5替换为6时:
foo.substring(6)
然后我得到一个错误:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: -1
子字符串(5)指向一个现有索引…它恰好指向一个空字符串。另一方面,子串(6)只是疯狂的谈话 当您执行
foo.substring(5)
时,它将获取从“e”后面的位置开始并在字符串末尾结束的子字符串。顺便说一句,起点和终点位置恰好相同。因此,空字符串。您可以认为索引不是字符串中的实际字符,而是字符之间的位置
---------------------
String: | a | b | c | d | e |
---------------------
Index: 0 1 2 3 4 5
根据,当起始索引大于字符串的长度时,子字符串将抛出错误
IndexOutOfBoundsException-如果
beginIndex为负值或大于
此字符串对象的长度
事实上,他们举了一个很像你的例子:
"emptiness".substring(9) returns "" (an empty string)
我想这意味着最好将Java字符串想象为以下内容,其中索引被包装在
中:
|0| A |1| B |2| C |3| D |4| E |5|
也就是说,字符串既有开始索引也有结束索引。这是因为substring函数返回一个“inclusive”子字符串。因此,索引5指向字符串末尾之前的位置,但位于字符串的最后一个显示字符之后 文档中显示了这一点:
来自字符串API javadoc:
public String substring(int beginIndex)
Returns a new string that is a substring of this
string. The substring begins with the "" character
at the specified index and extends to the end of this string.
public String substring(int beginIndex, int endIndex)
Returns a new string that is a substring of this
string. The substring begins at the specified beginIndex
and extends to the character at index endIndex - 1. Thus
the length of the substring is endIndex-beginIndex.
示例:
"unhappy".substring(2) returns "happy"
"Harbison".substring(3) returns "bison"
"emptiness".substring(9) returns "" (an empty string)
"hamburger".substring(4, 8) returns "urge"
"smiles".substring(1, 5) returns "mile"
参数:
beginIndex - the beginning index, inclusive.
Returns:
the specified substring.
Throws:
IndexOutOfBoundsException - if beginIndex is negative or
larger than the length of this String object.
====
这是设计的。如果您将索引作为字符串的大小,它将返回空字符串。我知道这个线程很旧,但这是一个非常基本的问题,我认为它需要澄清 这个问题恰到好处。我认为这是Java String.substring(intBeginIndex,intEndIndex)方法中的软件故障 来自Java文档 Java/C/C++和我所知道的所有其他语言都不将数组索引视为数组元素之间的“分隔符” 参数: beginIndex-开始索引,包含在内。 endIndex-结束索引,独占 由于语言不允许内存访问endIndex+1处的地址(包含最后一个数组元素所需的地址),endIndex命名错误,或者endIndex定义错误,必须: endIndex-结束索引,包含在内 最有可能的情况是第二个参数命名错误。应该是: 长度-从beginIndex开始所需字符串的长度 我们知道Gosling是基于C/C++语言的Java语法来熟悉的。从C+++字符串类中,我们可以看到方法定义为: 字符串substr(大小为pos=0,大小为npos)常量 请注意,方法定义中的第二个参数是“len”,表示长度 莱恩 子字符串中包含的字符数(如果字符串较短,则使用尽可能多的字符) testString有10个字符,索引位置为0到9。指定endIndex为10应始终引发IndexOutOfBoundsException(),因为testString没有endIndex为10
如果我们用C++的方法,用具体的值来测试JUnit中的方法,我们期望:
String testString=“testString”; 资产(testString.substring(4,6),equalTo(“String”) 但我们当然得到了期望:“字符串”但却是“St” 从索引0到字符串中字符“g”的testString长度为10个字符。 如果我们使用10作为'endIndex'参数 String testString=“testString”; 资产(testString.substring(4,10),equalTo(“String”) 来自JUnit的“Pass” 如果我们将参数2重命名为“lengthOfSubstringFromIndex0”,则不必进行endIndex-1计数,并且它不会抛出指定endIndex 10时所需的IndexOutOfBoundsException(),该值超出了基础数组的范围 这只是你必须记住这种方法的特殊性的时候之一。第二个参数命名不正确。Java方法签名应为:public String substring(int beginIndex,
int lengthOfSubstringFromIndex0)
<>或重新定义的方法匹配C++字符串::子字符串方法。重新定义当然意味着重写整个互联网,所以不太可能!感谢大家的提示,我正在查看同一个文档页面,但不知道我必须向下滚动才能获得更多详细信息…希望javadoc能对此有所说明,否则像我这样粗心的家伙会认为如果beginIndex=String.length(),会发生
IndexOutOfBoundsException
。