使用String.indexOf搜索零长度字符串“”的行为是否应视为未定义?

时间:2019-01-01 09:49:44

标签: java compatibility

[已编辑]
由于有些人在低估这个问题的全部内容上有困难,因此,我将添加一行或几行。在谈论API时,有一种叫做UNDEFINED BEHAVIOR的东西,这意味着作者无法保证某些编程动作的结果。该术语源于z80处理器时代,狡猾的程序员利用UNDOCUMENTED OPCODES的优势。这些操作码有时在优化中很方便,但是应该 即使这些操作码当时取得了一致的结果,也被视为UNDEFIND。但是,随着时间的流逝,公司开始提供与z80兼容的环境,而没有重现这些UNDOCUMENTED OPCODE的行为,并且猜测是什么,使用这些操作码的程序现在被破坏了。

这个故事的寓意是,您不应该依赖未定义的编程组件,例如未正确定义的操作码或API组件,因为它们的结果可能会不时更改。

现在,我们有了某种Java方法,该方法在一定条件下会产生一些奇怪的结果。所以我在问我是否应该将其结果视为未定义的行为或可靠的官方结果。除非您具有API编程或低级编程之类的知识,否则这个问题可能有点技术性,但是我仍然认为我的问题不明确,因为已经有人在回答我的问题。


我们都知道indexOf("")返回0,尽管没有正式记录。 但是您知道使用indexOf("", int num)时会发生什么吗? int num的逻辑答案比0更合理,并且实际上,如果字符串未还原测试的长度大于num,则返回num

但是那些弦短的人呢?好吧,旧版本的Java应该根据其源代码返回-1,因为它在开始时就防范str.length() <= num情况。但是,我只是注意到Java的android版本返回了str.length()的值。

因此,现在我很想知道“”搜索的行为应被认为不可靠。说可靠,我的意思是任何依赖这些行为的代码在Java的未来版本中都不会破坏。

2 个答案:

答案 0 :(得分:3)

Javadoc指出:

  

int java.lang.String.indexOf(String str,int fromIndex)

     

从指定索引处开始,返回指定子字符串首次出现时在此字符串中的索引。

     

返回的索引是为其的最小值k

k >= fromIndex && this.startsWith(str, k)
     

如果不存在这样的k值,则返回-1。

如果您通过fromIndex > str.length,则不会有k这样的k >= fromIndex && this.startsWith(str, k),因此它应该返回-1

但是,正如您所说,这不是已实现的行为。 indexOf(String str, int fromIndex)个呼叫:

static int indexOf(char[] source, int sourceOffset, int sourceCount,
                  char[] target, int targetOffset, int targetCount,
                  int fromIndex)

以:

开头
if (fromIndex >= sourceCount) {
    return (targetCount == 0 ? sourceCount : -1);
}

targetCount是传递给String的{​​{1}}的长度,而indexOf是您呼叫{{1}的sourceCount的长度},这意味着在您致电String时是否返回indexOffromIndex >= str.length()

这是文档错误或实施错误。

顺便说一句,我没有在Android上进行测试。我在JDK 8上进行了测试。

也就是说,我永远不会编写为str.length()调用str.indexOf("",fromIndex)的代码,因为在这种情况下我不希望在str.indexOf(subStr,index)中找到index >= str.length()(无论如何) subStr是否为空)。

由于它似乎毫无意义,因此我也永远不会将空的str传递给subStr

答案 1 :(得分:1)

在java8中,此代码:

    String s="abcdefg";
    System.out.println(s.indexOf(""));
    System.out.println(s.indexOf("",3));
    System.out.println(s.indexOf("",18);

输出:

0
3
7

其中7s的长度。

虽然Java doc(https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#indexOf-java.lang.String-int-)表示:

  

public int indexOf(String str,                      int fromIndex)

     

返回第一次出现的此字符串中的索引   指定的子字符串,从指定的索引开始。

     

返回的索引是为其的最小值k:

 k >= fromIndex  && this.startsWith(str, k)
     

如果不存在这样的k值,则返回-1。

所以我认为java8存在一个文档错误。我不敢说old version for android来了解您的Java版本,因此无法判断情况。