Java noargument构造函数:抛出不可能的异常,还是有空的catch块?
一个无参数构造函数抛出一个不可能的异常还是有一个空的catch块更好?比如说我有一门课是这样的
public class Foo {
private int num;
private String numString;
public Foo() throws NumberFormatException {
setNum("1");
}
public void setNum(String s) throws NumberFormatException {
// In reality, complex code goes here
num = Integer.parseInt(s);
numString = s;
}
}
编译器强制构造函数抛出NumberFormatException(这是永远不会发生的)或使用try/catch块。然而,有一个空的挡块是正确的吗?这通常是不受欢迎的
public Foo() {
try {
setNum("1");
}
catch (NumberFormatException e) { }
}
请注意,Foo将是一个库类,其他人也会使用它,所以让一个无参数构造函数抛出一个不可能的异常将令人困惑。还要注意,真正的异常是一个自定义异常,而不是NumberFormatException,这可能会让库用户更加困惑,他们可能会觉得在没有必要的时候,他们必须阅读自定义异常
# 1 楼答案
我想说,这取决于您的业务维护或个人编码风格,如果您选择抛出异常,那么使用自有和包装的异常可能会更好,如果您传递的参数不正确或没有意义,您可以立即抛出异常
无论必须抛出NumberFormatException,这都是一个公正的决定,您可以在哪里捕获它。它可能在您的library类、caller类或您不知道的某个地方。没有它,程序就会停止
在你的情况下,你认为无编号字符串是一个法律价值吗?如果是的话,你有责任在你的包中保持例外。
# 2 楼答案
NumberFormatException
是一个RuntimeException
,所以您不需要在throws
子句中列出它——只要假装它不在那里就行了。这适用于方法和构造函数RuntimeException
的任何子类(包括RuntimeException
本身)都是“未检查的异常”,这意味着编译器不会强制您在try/catch子句中检查它。相反,任何不是RuntimeException
子类的Exception
都很容易被调用为检查异常如果它是一个选中的异常(即,不是
RuntimeException
的子类),但您确信永远不会触发它,那么捕获它是安全的。与其完全吞咽它,不如将它包装成一个未检查的异常现在,您的代码已经编译,没有了一个
throws
子句来表示您从未期望抛出的异常,但是如果由于某些错误或将来的更改,该异常最终被抛出,则不会隐藏严重错误(阅读注释的读者注意:我最初在代码示例
throw new RuntimeException(e)
中有,但是Stephen C和Peter Lawrey指出,在Java 1.4.2和更新版本中,断言错误更好)# 3 楼答案
我会说:永远不要空的捕捉块(不管是什么情况)。正如@yshavit所指出的,吞下一个可能的错误不是一个好的做法
正如@stephen-c所说,使用断言是一种前进一步的选择,但这种解决方案有两个缺点:
所以我的建议是@yshavit提案
# 4 楼答案
既然s必须是一个数字,为什么不通过setNum()传递一个整数,而不是当前字符串?整数始终可以解析为字符串