java 为什么 String.indexOf 不使用异常而是在未找到子字符串时返回 -1?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/859494/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:06:02  来源:igfitidea点击:

Why String.indexOf do not use exception but return -1 when substring not found?

javaexception-handling

提问by ariso

Why String.indexOf do not use exception but return -1 when substring not found?

为什么 String.indexOf 不使用异常而是在未找到子字符串时返回 -1?

The purpose of this question is: when we start custom exception.

这个问题的目的是:我们什么时候开始自定义异常。

I believe avoid the need to return special error code is right design path.

我相信避免需要返回特殊错误代码是正确的设计路径。

What's your opinion?

你怎么看?

回答by Paul Tomblin

As a rule of thumb, if the purpose of a method is to check for something, then the lack of that something shouldn't be an exception. If the method is assuming that something is true, then the absence of that something would be an exception. Thus "File.exists()" doesn't throw a FileNotFoundException, but "File.open()" does.

根据经验,如果方法的目的是检查某些东西,那么缺少某些东西不应该是例外。如果该方法假设某事为真,则该某事的缺失将是一个例外。因此,“File.exists()”不会抛出 FileNotFoundException,但“File.open()”会。

回答by z -

exceptions are for exceptional cases, when a string does not contain a letter, that's hardly exceptional, unless you are using it for some extreme case. If that's what you are doing, you can always choose to throw your own exception.

例外是针对特殊情况,当字符串不包含字母时,这几乎不是例外,除非您将它用于某些极端情况。如果这就是你正在做的,你总是可以选择抛出你自己的异常。

回答by Gishu

Last I heard on that was...

最后我听到的是...

'You throw an exception when your method is unable to do what it promises to' - Jeff Richter CVC 2nd ed

“当您的方法无法实现其承诺时,您会抛出异常”——Jeff Richter CVC 第二版

  • IndexOf() promises you to return the index of the first occurrence of a char/string. It would have thrown an exception if it was unable to do its job for some reason. It did its job but didn't find the string and hence returns -1 to convey the not-found result.
  • File.Open() will throw a FileNotException for a non-existing filepath since it is unable to do what it promises .. i.e. open the specified file.
  • IndexOf() 承诺您返回字符/字符串第一次出现的索引。如果由于某种原因无法完成其工作,它将引发异常。它完成了它的工作,但没有找到字符串,因此返回 -1 以传达未找到的结果。
  • File.Open() 将为不存在的文件路径抛出 FileNotException,因为它无法执行它所承诺的 .. 即打开指定的文件。

回答by egaga

returning -1 is almost as horrible as throwing an exception. The correct way would be to use option type if language just supported it better. In normal situation where there is result, you wrap the result in object and return that. Otherwise you return an object representing the "not result" situation.

返回 -1 几乎和抛出异常一样可怕。如果语言更好地支持它,正确的方法是使用选项类型。在有结果的正常情况下,您将结果包装在对象中并返回。否则,您将返回一个表示“非结果”情况的对象。

In call site you have to check which one was it; you can't just use the return value because of their super type, they have to be inspected via pattern matching.

在呼叫站点中,您必须检查它是哪个;由于它们的超类型,您不能只使用返回值,它们必须通过模式匹配进行检查。

In pseudo syntax:

在伪语法中:

class Option[a] = Some[a] | None,

where a is generic type parameter, Some represents a result with value and None non-result without value.

其中 a 是泛型类型参数, Some 表示有值的结果, None 表示没有值的非结果。

in indexOf case you would have:

在 indexOf 的情况下,您将拥有:

Option[Integer] indexOf(char c) = {
   if(found) return Some(index)
   else return None
}

and you use that this way:

你这样使用它:

result = "uncle".indexOf('c')
result match {
  Some(i) => System.out.println("index was: " + i);
  None => System.out.println("no value");
}

If you omitted either Some or None from matching (which is kinda generalized switch), compiler would give you a warning.

如果您从匹配中省略 Some 或 None (这是一种通用开关),编译器会给您一个警告。

回答by RedFilter

Lots of good answers here. This is a design issue where pragmatism has taken precedence over following "rules". In this case, there are some conflicting "rules":

这里有很多很好的答案。这是一个实用主义优先于遵循“规则”的设计问题。在这种情况下,存在一些相互冲突的“规则”:

  • avoid using special values as return data (not self-documenting, requires developer to handle special value in a distinct way from other code)
  • 避免使用特殊值作为返回数据(不是自我记录,需要开发人员以不同于其他代码的方式处理特殊值)

vs.

对比

  • don't throw exceptions during routine execution of code, only when something unexpected happens
  • 不要在代码的日常执行过程中抛出异常,只有在发生意外时才抛出异常

I agree with this design decision. If you do not, however, you can always write your own code to check for the existence of a string before checking its index. Do not be a prisoner of your language, bend it to your will. Languages are meant to be tortured!

我同意这个设计决定。但是,如果您不这样做,您始终可以编写自己的代码在检查字符串索引之前检查字符串是否存在。不要成为你语言的囚徒,让它服从你的意愿。语言是用来折磨的!

回答by user61491

Also because exceptions are expensive in terms of performance

也因为异常在性能方面是昂贵的

回答by Gromer

It's a lot easier to deal with checking for a -1 than catching an exception.

处理检查 -1 比捕获异常容易得多。

回答by Chris Thornhill

Aside from the arguments against exceptions in general, I would add that -1 can be a useful result from indexOf and lastIndexOf, not just a special value. For instance, to parse the filename from a string that may or may not contain a path:

除了一般反对异常的论点之外,我还要补充一点,-1 可能是 indexOf 和 lastIndexOf 的有用结果,而不仅仅是一个特殊值。例如,要从可能包含或不包含路径的字符串中解析文件名:

String filename = arg.substring(arg.lastIndexOf('/') + 1);

While perhaps a contrived example, this would be a bit more cumbersome with exceptions.

虽然这可能是一个人为的例子,但如果有例外,这会有点麻烦。

回答by Alberto Zaccagni

I think that one has to throw an exception when something unexpectedhappens. That said, a substring not found in a String is not that unexpected, can happen, it is a reasonable result.

我认为当意外发生时必须抛出异常。也就是说,在 String 中找不到的子字符串并不是那么出乎意料,可能会发生,这是一个合理的结果。

I agree with you that one should try to avoid returning error codes, but in this case we have only two choices, string found or string not found.

我同意你应该尽量避免返回错误代码,但在这种情况下,我们只有两个选择,找到字符串或未找到字符串。

回答by Tim Lovell-Smith

Until the author of Java's string.indexOftells us the actual history...

直到 Java 的作者string.indexOf告诉我们真实的历史......

Let's suppose we had to design it from scratch, some obvious design constraints for this problem:

假设我们必须从头开始设计它,这个问题有一些明显的设计限制:

  1. indexOfmust return a numeric value, so that when a match is found, you know where it is
  2. valid indexes are guaranteed to be always integers
  3. array (and string) indexes are zero-based in Java
  4. Java is strongly typed
  5. the integer numeric types are signed in Java
  1. indexOf必须返回一个数值,这样当找到匹配项时,您就知道它在哪里
  2. 有效索引保证总是整数
  3. 数组(和字符串)索引在 Java 中从零开始
  4. Java 是强类型的
  5. 整数数字类型在 Java 中签名

Given those basic constraints, some possible choices for function return type the would be integer (ideally of a type large enough to represent the last index in the largest possible string), OR... Object(and perhaps return null to indicate not found). But in practice returning Objectwould be neither efficient nor user-friendly, due to the need to check its validity and cast before usage for the found case - so it's not really a viable option!

鉴于这些基本约束,函数返回类型的一些可能选择将是整数(理想情况下,类型足够大以表示最大可能字符串中的最后一个索引),或... Object(可能返回 null 以指示未找到)。但在实践中,返回Object既不高效也不用户友好,因为需要在使用前检查其有效性并为找到的案例进行转换 - 所以这不是一个真正可行的选择!

So let's go with an integer. Do we want to throw an exception if not found? Throwing exceptions has multiple problems of its own - creating exception objects and jumping to exception handlers can be quite inefficient, and writing try/catch blocks around indexOfcalls is no fun either!

所以让我们用一个整数。如果找不到,我们要抛出异常吗?抛出异常有其自身的多个问题——创建异常对象并跳转到异常处理程序可能非常低效,并且围绕indexOf调用编写 try/catch 块也没有乐趣!

So let's say we've narrowed it down: it has to return a (signed) integer type, and notthrow an exception. Now which integer value should it return to represent not found?

所以假设我们已经缩小了范围:它必须返回一个(有符号的)整数类型,而不是抛出异常。现在它应该返回哪个整数值来表示未找到?

In order to allow searching in strings as large as possible, we should reserve all positive integers for usage as meaning successfully found. Conversely, none of the negative numbers is needed to represent a 'found' index, so all are potentially available to use as return codes representing 'not found'.

为了允许在尽可能大的字符串中搜索,我们应该保留所有正整数作为成功找到的意思。相反,表示“找到”索引不需要任何负数,因此所有负数都可能用作表示“未找到”的返回代码。

If we could have picked any negative number, to represent not found, or just said 'all negative return values mean not found' it would do the job... But would it be the best design?

如果我们可以选择任何负数来表示未找到,或者只是说“所有负返回值都意味着未找到”,那么它就可以完成工作……但这会是最好的设计吗?

What are some reasons to use -1 instead of other negative numbers? My favorite reasons are simply '-1 is easy for everyone to remember, and you can do exact equality tests on it'. (Instead of being forced to use inequalities and think about off-by-one problems like whether you want less-than or less-than-or-equal, and what value to compare with, zero or negative one)

使用 -1 而不是其他负数的一些原因是什么?我最喜欢的理由很简单,“-1 对每个人来说都很容易记住,而且你可以对它进行精确的相等性测试”。(而不是被迫使用不等式并考虑逐一问题,例如您想要小于还是小于或等于,以及要比较的值是零还是负值)

I also sometimes admire Chris's reason that (paraphrasing) 'it works nicely with substring(foundIndex + 1)'.

我有时也很欣赏 Chris 的理由(解释)“它与substring(foundIndex + 1)'配合得很好。