我经常面对这个问题。让我们看一个简单的例子,我得到了这个简单的方法:它检索String
中String[]
的位置。
public int getStringPosition(String s, String[] text) {
for (int i = 0; i < text.length; i++) {
if (text[i].equals(s)) {
return i;
}
}
return text.length;
}
但是如果String不在数组中怎么办?这里,它返回数组的大小(int
,它不能正常使用该方法)。它也可以返回-1
。我希望它会返回null,但这似乎不可能。
无论如何,这个方法将通过其他一些方法在同一个类中使用。我的问题非常笼统,如何处理无法返回预期的情况?
答案 0 :(得分:5)
如果s
不在text
中的情况不是调用方法的有效方法,则应抛出异常,例如IllegalParameterException。
但是如果可以通过这种方式调用方法,则不应抛出异常,因为它是有效的预期用法。在这种情况下你可以例如返回-1
。
但是-1
在这种情况下是一个“神奇数字”,这是一种糟糕的做法,所以你应该为此声明一个常量。
private static final int STRING_NOT_IN_TEXT=-1;
/**
* @return first position of 's' in 'text'
* and if 's' is not in 'text' returns NOT_IN_TEXT
*/
public static int getStringPosition(final String s, final String[] text) {
for (int i = 0; i < text.length; i++) {
if (text[i].equals(s)) {
return i;
}
}
return STRING_NOT_IN_TEXT;
}
P.S。您可能还想检查text
是否null
并处理此案例,而不是让系统抛出NullPointerReference
。
答案 1 :(得分:5)
如果无法找到字符串构成错误,异常情况,那么您应该向调用者抛出一些异常。如,
throw new RuntimeException("String not found");
如果无法找到字符串是调用者想要在代码的正常流程中处理的正常情况,那么您应该使用特殊的返回值。对于这种类型的搜索方法,没有正常的返回值可能是否定的,并且约定是返回-1
,String.indexOf
和List.indexOf
。如果遵循该约定,您实际上可以使用一行实现方法体:
return java.util.Arrays.asList(text).indexOf(s);
注意:此更改会稍微区别null
。在您的方法中有三件事可能为null:搜索字符串,数组和数组元素。如果传递空数组,或者当遇到null元素时,您当前的代码会抛出NullPointerException
,但会静默忽略空搜索字符串。通过推迟到List.indexOf
,允许所有数组元素也为空,允许在数组中搜索空值。这可能是一个无害的差异,但一个精心设计的方法会考虑这些问题。例如,您可能更喜欢将空搜索字符串视为无效输入,并在这种情况下立即抛出异常。
完全记录的公共方法还会考虑数组中多个匹配元素的情况:它应该返回最低匹配索引还是任何匹配索引?如果任何索引是可接受的,那么它是否必须始终为具有相同参数的重复调用返回相同的索引? (假设的多线程搜索实现很容易打败返回最低索引的“明显”假设,因为您无法预测哪个CPU核心将首先找到匹配。)
还要考虑该方法可以声明为static
。
答案 2 :(得分:4)
这是任意的。一些开发人员将抛出异常,其他人将返回一些特殊值,如-1。最重要的是在任何情况下准确定义您的方法所做的事情,因此将使用您的代码的人知道他们正在使用的是什么。
答案 3 :(得分:2)
我想到了两件事:
a)对于返回“index”的方法非常有效,该索引指向任何类型的序列以返回-1以指示“找不到匹配”
b)可能也只能抛出一些运行时异常,例如IllegalArgumentException
当考虑选项“b)”时,它有时会有两个方法,比如findIndex()和getIndex();按照惯例,“查找”方法总会引发异常;而另一个会返回null / -1或其他值。但是,当然,这是您为项目/团队/您的任何内容定义本地的东西。换句话说:所有处理代码的人都必须明白调用findXyz()可能会抛出异常;并且还有其他方法不会抛出。
而且,作为旁注,您应该始终尝试与“标准解决方案”保持一致。我的意思是;假设您的代码将使用集合:
int getIndex(String stringToSearch, List<String> stringsToSearch) {
return stringsToSearch.indexOf(stringToSearch);
猜猜这将返回什么......现在问问自己是否希望基于阵列的解决方案与java标准集合做同样的事情......
(最后的注意事项:是的,我的变量名称非常长,但我仍然认为冗长的名字比“s”更好......因为后者并没有告诉你任何有关这些名称的用途参数)。
答案 4 :(得分:2)
遵循常见和已知的编码约定:您的方法看起来像 String.indexOf(String),因此在找不到输入时只返回-1。例外应该是&#34;例外&#34;并且没有在数组中找到字符串,而不是。
如果你想要更多OO,你可以实现类似
的东西UIViewController
使用 Found 和 NotFound 类实现的接口Result,以区别对待;总的来说,虽然这个解决方案看起来有点矫枉过正。
答案 5 :(得分:1)
由于您要返回一个primite类型,因此无法返回null。返回Integer而不允许null。
尽管如此,我同意上面的评论员,例外是处理这个问题的正确方法
答案 6 :(得分:1)
如果找不到任何内容,则返回null是一个很好的模式。您可以使用Integer
代替int
。 Integer
类在对象中包装基本类型int
的值。类型为Integer
的对象包含单个字段,其类型为int
。这就是为什么你可以返回null,如果你像
public Integer getStringPosition(String s, String[] text)
答案 7 :(得分:1)
您可以使用此处的建议:
Integer
作为返回类型并返回null
值。然而,null
也被视为反模式(谷歌“无效十亿美元的错误”)如果您不介意上述内容,请继续使用其中一个选项(许多程序员经常使用这些选项)
您还可以使用Optional / Maybe / Option类型
public Optional<Integer> getStringPosition(String s, String[] text) {
for (int i = 0; i < text.length; i++) {
if (text[i].equals(s)) {
Optional.of(i);
}
}
return Optional.empty();
}
Java 8中提供了 Optional
。如果您使用的是旧版本,则可以使用众多可用实现中的一种(例如,George Chanturia)