对于从客户端角度来看有效的无效输入,要引发哪个异常

2022-08-31 23:40:29

我正在编写代码来查找和交叉2行。当线的斜率相等时,它们不相交。但另一方面,斜率相等的输入是完全有效的。

public static Point calculateIntersection(Line line1, Line line2) {

    if (line1 == null || line2 == null) {
        throw new NullPointerException(" some message ");
    }

    if (line1.getConstant() == line2.getConstant()) {
        return new Point(0, line1.getConstant());
    }

    if (line1.getSlope() == line2.getSlope()) {
        throw new IllegalArgumentException("slopes are same, the lines do not intersect.");
    }

    int x = (line2.getConstant() - line1.getConstant()) / (line1.getSlope() - line2.getSlope());
    int y = line1.getSlope() * x + line1.getConstant();

    return new Point(x, y);
}

问题是抛出非法参数异常是正确的做法吗?由于输入是有效的,它并不能完全说服我。

自定义异常是正确的做法吗?听起来像是一个不错的选择,但额外的意见会有所帮助。

谢谢


答案 1

问题是抛出非法的论点例外是正确的做法吗?

这取决于你想要/需要如何“框架”这个条件;也就是说,它是一个错误,用户输入错误,还是程序应该能够处理的东西?

  • 如果两条线不相交的情况无疑是一个“错误”,那就没问题了。这就是异常的设计目的。(请注意,这是一个未经检查的异常,因此期望它不会被捕获/恢复。IllegalArgumentException

  • 如果这是您希望程序能够自行恢复的情况,则最好使用自定义异常。这样,您可以减少代码被(例如)库方法抛出(例如)...比表示“两条线相交”以外的其他含义。IllegalArgumentException

  • 如果这种情况是您希望作为输入验证的一部分向最终用户报告的情况,则一般的“验证错误”异常可能比特定的自定义异常更合适。但是,此方法看起来并不像是设计为(仅)用于用户输入验证。


在某些情况下,最好不要抛出异常,但(IMO)这不是这些上下文之一。替代项返回或返回一个值,该值表示调用代码“没有这样的点”。替代方案的问题是:nullPoint

  • 如果您退回申请必须处理的情况...或者会有NPE。nullnull
  • 没有自然的例子可以用来表示“不是一个点”。Point

这并不是说你不能让这些替代方案发挥作用。只是在这种情况下,这样做可能会有更多的工作要做,而且可能不会有切实的回报。


答案 2

这几乎肯定不应该引发异常,因为使用任意两个值调用这样的方法是完全有意义的。您已经适当地处理了空值。Line

您还非常合理地定义了类在一种定义不明确的输入情况下的行为,即两条重合的“常量”(水平)线,在该行上返回点。同样,您应该为定义不明确的输入的其他情况选择返回值:垂直线重合,既不水平也不垂直的重合线,以及非重合平行线。x=0

在我看来,最后一种情况(非重合平行线)最自然的结果将是 ,反映了没有交点的事实。null

然后由客户端决定空交集是否保证异常、错误消息或其他任何内容。例如,一个交互式 shell 提示用户输入要相交的行,可能会打印一条错误消息并要求用户重试。一些更复杂的计算,例如,如果产生平行线的约束相互矛盾,则试图为其搜索定义边界的线性优化器可能想要抛出。IllegalArgumentException

当然,所有这些情况下的返回值(重合行或非重合平行线)都应精确地记录在方法的 javadoc 中。


推荐