Java 我应该如何做到这一点而不抛出异常?
我对Java相当陌生,我正试图了解异常以及它们应该在什么时候使用。我一直在使用它们作为错误检查的一种形式,但我遇到过一些人说,异常应该只用于程序无法控制的事情,例如用户错误 我有一个函数,对于给定的二维直线,计算xMin和xMax之间的所有y值。如果直线是垂直的,此函数将引发异常,因为不可能计算垂直直线上y的所有值。在两个y值之间也有一个等价的函数查找点,如果直线是水平的,则会抛出一个错误Java 我应该如何做到这一点而不抛出异常?,java,exception-handling,Java,Exception Handling,我对Java相当陌生,我正试图了解异常以及它们应该在什么时候使用。我一直在使用它们作为错误检查的一种形式,但我遇到过一些人说,异常应该只用于程序无法控制的事情,例如用户错误 我有一个函数,对于给定的二维直线,计算xMin和xMax之间的所有y值。如果直线是垂直的,此函数将引发异常,因为不可能计算垂直直线上y的所有值。在两个y值之间也有一个等价的函数查找点,如果直线是水平的,则会抛出一个错误 findPointsInRangeOfX (int xMin, int xMax) throws Line
findPointsInRangeOfX (int xMin, int xMax) throws LineIsVerticalException {
// check if line is vertical
// if vertical, throw an exception
// else calculate the y values for each integer between xMin and xMax
// return y values
}
我调用此函数作为查找给定窗口内直线上所有点的一部分,该窗口由最小和最大x和y值给定。我不检查此函数中的线条是否垂直;相反,我依赖于签入findPointsInRangeOfX并在方法周围使用try-and-catch块
pointsInWindow (int xMin, int xMax, int yMin, int yMax) {
try {
// Find list of all the points between xMin and xMax.
// Remove from list all points not between yMin and yMax
}
catch (LineIsVerticalException e) {
// If line is vertical, cannot find points between xMin and xMax
try {
// Instead, find list of all points between yMin and yMax
// Remove from list all points not between xMin and xMax
}
catch (LineIsHorizontalException e) {
// This part will never be reached because the line is vertical
// But the compiler complains if the exception isn't caught
}
}
}
这样行吗?我并没有为这样的错误抛出异常-有一条垂直线没有错-但我用它告诉pointsInWindow它需要找到y值之间的点,而不是x值之间的点。我是否应该重复检查以查看pointsInWindow函数中的线条是否垂直,而不是使用try-catch块?如果我重复了检查,我是否应该一起消除LineIsVerticalException?您必须坚持单一责任原则:每种方法都做一件事。 现在你的方法做两件事:检查它是否垂直/水平,并计算一些东西 另一个注意事项是:不要对程序流使用异常 您应该将其拆分为以下内容:
bool isVertical(parameters){}
bool isHorizontal(parameters){}
SomeClass CalculateVertical(parameters){}
SomeClass CalculateHorizontal(parameters){}
if(isVertical(something)){
CalculateVertical(something);
else if (isHorizontal(something)){
CalculateHorizontal(something);
}
您的程序流可能如下所示:
bool isVertical(parameters){}
bool isHorizontal(parameters){}
SomeClass CalculateVertical(parameters){}
SomeClass CalculateHorizontal(parameters){}
if(isVertical(something)){
CalculateVertical(something);
else if (isHorizontal(something)){
CalculateHorizontal(something);
}
实施示例:
SomeClass CalculateVertical(something){
if(!isVertical(something)) { throw new IllegalArgumentException() }
// Calculations
}
请注意,程序员不必捕获此异常。或者您可以进行如下修改:
pointsInWindow (int xMin, int xMax, int yMin, int yMax) {
try {
// Find list of all the points between xMin and xMax.
// Remove from list all points not between yMin and yMax
}
catch (LineIsVerticalException e) {
// If line is vertical, cannot find points between xMin and xMax
// do something..
}
catch (LineIsHorizontalException e) {
// unless LineIsVerticalException is superclass of LineIsHorizontalException,
// this will work
// do something ..
}
}
}
一般来说,我会尝试对意外问题(例如网络故障)使用异常,而不仅仅是边界情况。然而,这是一个模糊的区别,取决于您特定的应用程序上下文 专门针对你的问题。拆分功能怎么样。生成两个函数来检测给定行是水平行还是垂直行(例如布尔值isVertical()) 在pointsInWindow函数中,您可以首先检查您是否正在处理垂直/水平线的特殊情况,如果没有,则进一步调用findPointsInRange方法 尽量不要复制逻辑,因为这违反了DRY原则,并且在维护代码时会导致进一步的问题 希望这有帮助,
马库斯同意。我会很懒,只会抛出IllegalArgumentException。这是一个已存在的异常,未选中。这将迫使用户在尝试调用方法之前验证输入。因此,我是否应该在CalculateVertical中假设我确实得到了一条垂直线,并且没有任何检查该方法的操作?@Emma:你永远不应该信任用户。我会在
CalculateVertical
中再次调用isVertical
,并抛出一个异常(如Kayaman所说的IllegalArgumentException
),如果它返回false
@Emma,你可以在CalculateVertical方法中再次检查isVertical,但是如果我在CalculateVertical中抛出一个异常,无论如何,我必须在pointsInWindow中使用try catch,这样我就回到了以前的位置,只是在那里额外调用了isVertical。除非我误解了什么?你可能会发现这个堆栈中的一些流在什么时候抛出异常很有趣,就像这个带有其他材料链接的堆栈一样