4

请参阅下面的两个示例。假设这两个类都包含属于广泛使用的 API 库的公共方法。

AClass.java更容易编写(可能由于噪音较小而更容易阅读),但是当检测到错误时,堆栈跟踪中的第一个方法是内部方法(nullCheck(...))并且异常消息不是指该方法。这会给用户带来不必要的困惑吗?我的意思是在用户思考的意义上:“这是一个引发异常的内部方法,一定是库中的错误,而不是我的程序中的错误。什么* * 无用的库......”

BClass.java写起来比较麻烦(连同它的所有 if 语句),但是当检测到错误时,堆栈跟踪的第一行会指出第一次检测到错误的 API 方法(由用户调用)。这是否更有可能让用户认为:“我正在从我的代码中调用该方法,一定是我传入的参数有问题”。

在公共 API 中检查参数的有效性时,哪种是引发异常的首选方式?或者这两个例子被认为是相等的?

public class AClass {
public void publicApiMethod1(String a){
    nullCheck(a, "a");
    // do something...
}
public void publicApiMethod2(String a, String b, String c){
    nullCheck(a, "a");
    nullCheck(b, "b");
    nullCheck(c, "c");
    // do something...
}

private void nullCheck(Object a, String argName) {
    if(a == null){
        throw new NullPointerException("Null argument: " + argName);
    }
}
}


public class BClass {
public void publicApiMethod1(String a){
    if(a == null){
        throw new NullPointerException("Null argument: 'a'");
    }
    // do something...
}

public void publicApiMethod2(String a, String b, String c){
    if(a == null){
        throw new NullPointerException("Null argument: 'a'");
    }
    if(b == null){
        throw new NullPointerException("Null argument: 'b'");
    }
    if(c == null){
        throw new NullPointerException("Null argument: 'c'");
    }
    // do something...
}
}
4

4 回答 4

5

如果您的错误消息是描述性的(确实如此),那么没有人会费心查看堆栈跟踪。因此第一种形式更好,因为它封装了验证逻辑。

请注意,各种库中有大量可供使用的断言方法,请参阅:Objects.requireNonNullValidate.notNull)。

于 2012-05-29T22:00:11.007 回答
2

我会这样做,基本上基于你的AClass

public void publicApiMethod2(String a, String b, String c){
    try {
        nullCheck(a, "a");
        nullCheck(b, "b");
        nullCheck(c, "c");
    }
    // catch the NullPointerException,
    // and any other Exception explicitly thrown by your validation methods
    catch (NullPointerException e) { 
         throw new IllegalArgumentException(e.getMessage());
    }
    // do something...
} 

这样,用户就会得到一个明确的消息一个指向公共方法的堆栈跟踪。

于 2012-05-29T22:04:03.770 回答
1

在你的 b 课上你为什么不使用

if( (c == null)|| (b == null)|| (a == null) ){
 //thrown my red ball
 }

不那么烦人,更易读

于 2012-05-29T21:57:57.310 回答
1

我认为 A 类很好,只要你用@throws. 我已经看到很多库会在堆栈中投入更深。重要的是让用户了解为什么会抛出错误以及他们可以做些什么来避免它。

于 2012-05-29T22:04:24.647 回答