Java:方法()处理错误调用的正确方法

Java:方法()处理错误调用的正确方法,java,return,Java,Return,我经常遇到这个问题。让我们看一个简单的例子,我得到了这个简单的方法:它检索字符串在字符串[]中的位置 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; }

我经常遇到这个问题。让我们看一个简单的例子,我得到了这个简单的方法:它检索
字符串
字符串[]
中的位置

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;
}
public int getStringPosition(字符串s,字符串[]文本){
for(int i=0;i
但是如果字符串不在数组中怎么办?在这里,它返回数组的大小(正常使用该方法无法得到的
int
)。它还可以返回
-1
。我希望它返回null,但这似乎不可能


无论如何,这个方法将被其他一些方法用在同一个类中。我的问题很一般,如何处理无法返回预期内容的情况?

您不能返回null,因为您返回的是primite类型。改为返回整数,将允许null


尽管如此,我同意上面的评论员的观点,异常是处理此问题的正确方法

如果
s
不在
text
中的情况不是调用该方法的有效方式,您应该抛出异常,例如非法参数异常

但是,如果可以这样调用该方法,则不应该抛出异常,因为它是有效的预期用法。在这种情况下,您可以返回
-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;
}
private static final int STRING_NOT_IN_TEXT=-1;
/**
*@返回“文本”中“s”的第一个位置
*如果's'不在'text'中,则返回not_in_text
*/
公共静态int getStringPosition(最终字符串s,最终字符串[]文本){
for(int i=0;i

另外,您可能还需要检查
文本是否为
null
,并处理这种情况,而不是简单地让系统抛出
NullPointerReference

它是任意的。一些开发人员将抛出异常,其他人将返回一些特殊值,如-1。最重要的是准确地定义您的方法在任何情况下的作用,以便使用您的代码的人知道他们在使用什么。

如果找不到字符串构成了一个错误,一种异常情况,那么您应该向调用者抛出一些异常。例如:

throw new RuntimeException("String not found");

如果无法找到字符串是调用方希望在正常代码流中处理的正常情况,那么应该使用特殊的返回值。对于这种类型的搜索方法,正常的返回值不能为负值,惯例是返回
-1
,就像和do一样。如果遵循该约定,实际上可以用一行代码实现方法体:

return java.util.Arrays.asList(text).indexOf(s);
注意:该更改对
null
的处理方式有点不同。在您的方法中有三个元素可以为null:搜索字符串、数组和数组的元素。如果传递空数组,或者当当前代码遇到空元素时,会抛出一个
NullPointerException
,但会自动忽略空搜索字符串。通过遵从
List.indexOf
,所有数组元素也允许为null,从而允许在数组中搜索null值。这可能是一个无害的区别,但一个精心设计的方法会考虑这些问题。例如,您可能更愿意将空搜索字符串视为无效输入,并在这种情况下立即抛出异常

完全文档化的公共方法也会考虑数组中多个匹配元素的情况:它是否返回最低匹配索引或任何匹配索引?如果任何索引都是可接受的,那么对于使用相同参数的重复调用,它必须一致地返回相同的索引吗?(一个假设的多线程搜索实现可以很容易地击败返回最低索引的“明显”假设,因为您无法预测哪个CPU内核将首先找到匹配项。)


也认为该方法可以声明为代码> static .

如果没有发现,它是返回null的好方法。您可以使用

Integer
而不是
int
Integer
类将原语类型
int
的值包装在对象中。
Integer
类型的对象包含一个类型为
int
的字段。这就是为什么你可以返回null,如果你喜欢它

public Integer getStringPosition(String s, String[] text)

我想到两件事:

a) 对于返回指向任何序列的“索引”的方法来说,返回-1表示“未找到匹配项”是非常有效的

b) 也可以只抛出一些运行时异常,比如IllegalArgumentException

当考虑选项“b”时,有时有两种方法会有所帮助,比如findIndex()和getIndex();按照惯例,“find”方法总是抛出异常;而另一个将返回null/-1或其他值。但当然,这是您为您的项目/您的团队/您的任何东西在本地定义的东西。换句话说:所有处理代码的人都必须明白调用findXyz()可能引发异常;还有其他一些方法不会抛出

另外,作为旁注,您应该始终尝试与“标准解决方案”保持一致。我的意思是;假设您的代码将使用集合:

int getIndex(String stringToSearch, List<String> stringsToSearch) {
  return stringsToSearch.indexOf(stringToSearch);
int-getIndex(字符串字符串搜索,列表字符串搜索){
返回stringsToSearch.indexOf(stringToSearch);
猜猜这将返回什么…现在问问自己是否希望基于阵列的解决方案与java标准集合做同样的事情

(最后一个旁注:是的,我的变量名是
Result search(T something,Set<T> someSet);
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();
}