有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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,这可能会让库用户更加困惑,他们可能会觉得在没有必要的时候,他们必须阅读自定义异常


共 (4) 个答案

  1. # 1 楼答案

    我想说,这取决于您的业务维护或个人编码风格,如果您选择抛出异常,那么使用自有和包装的异常可能会更好,如果您传递的参数不正确或没有意义,您可以立即抛出异常

    无论必须抛出NumberFormatException,这都是一个公正的决定,您可以在哪里捕获它。它可能在您的library类、caller类或您不知道的某个地方。没有它,程序就会停止

    在你的情况下,你认为无编号字符串是一个法律价值吗?如果是的话,你有责任在你的包中保持例外。

  2. # 2 楼答案

    NumberFormatException是一个RuntimeException,所以您不需要在throws子句中列出它——只要假装它不在那里就行了。这适用于方法和构造函数

    RuntimeException的任何子类(包括RuntimeException本身)都是“未检查的异常”,这意味着编译器不会强制您在try/catch子句中检查它。相反,任何不是RuntimeException子类的Exception都很容易被调用为检查异常

    如果它是一个选中的异常(即,不是RuntimeException的子类),但您确信永远不会触发它,那么捕获它是安全的。与其完全吞咽它,不如将它包装成一个未检查的异常

    try {
        thisCodeCanNeverThrowAnIOException();
    }
    catch (IOException e) {
        throw new AssertionError(e); // juuust in case!
    }
    

    现在,您的代码已经编译,没有了一个throws子句来表示您从未期望抛出的异常,但是如果由于某些错误或将来的更改,该异常最终被抛出,则不会隐藏严重错误

    (阅读注释的读者注意:我最初在代码示例throw new RuntimeException(e)中有,但是Stephen C和Peter Lawrey指出,在Java 1.4.2和更新版本中,断言错误更好)

  3. # 3 楼答案

    我会说:永远不要空的捕捉块(不管是什么情况)。正如@yshavit所指出的,吞下一个可能的错误不是一个好的做法

    正如@stephen-c所说,使用断言是一种前进一步的选择,但这种解决方案有两个缺点:

    1. 可能“操作/生产”服务器上没有启用断言,因此您真正拥有的与空catch块非常相似
    2. 如果在服务器上启用了它们,那么在执行这段代码的过程中出现的错误将表明您的应用程序中存在错误,因为出现了一些出乎意料的情况(“这永远不会发生”,但它确实发生了!所以…)

    所以我的建议是@yshavit提案

  4. # 4 楼答案

    既然s必须是一个数字,为什么不通过setNum()传递一个整数,而不是当前字符串?整数始终可以解析为字符串