Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么是;“超出范围”;不为'抛出;子字符串(起始索引、结束索引)和#x27;_Java_Substring - Fatal编程技术网

Java 为什么是;“超出范围”;不为'抛出;子字符串(起始索引、结束索引)和#x27;

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

在Java中,我使用的是
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