当前位置: 首页 > 知识库问答 >
问题:

Java无参数构造函数:抛出不可能的异常,还是有空的catch块?

亢雅懿
2023-03-14

无参数构造函数抛出一个不可能的异常还是有一个空的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,这可能会让库用户更加困惑,他们可能会觉得在没有必要的时候必须阅读自定义异常。

共有3个答案

羊舌高爽
2023-03-14

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

无论必须抛出NumberFormatException是什么,这都是一个公正的决定,你可以在哪里找到它。它可能在你的library类中,或者caller类中,或者在你不知道的地方。没有它,程序就会停止。

在您的情况下,您是否认为no number字符串是一个合法值,如果是,您有责任在包中保留例外。

郭翰墨
2023-03-14

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

姚善
2023-03-14

NumberFormatException是一个RuntimeException,因此您无需将其列在throws子句中——只需假装它不存在。这适用于方法和构造函数。

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

如果它是一个检查过的异常(也就是说,不是RuntimeException的子类),但您确定永远无法触发它,那么捕获它是安全的。与其完全吞下它,最好将它包装在未经检查的异常周围。

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

现在你的代码已经编译好了,没有了一个throws子句来处理一个你从来没想过会被抛出的异常,但是如果由于某种错误或将来的更改,这个异常最终被抛出,你也不会隐藏一个严重的错误。

(请注意那些阅读评论的人:我最初在代码示例中抛出了新的RuntimeException(e),但Stephen C和Peter Lawrey指出,在Java1.4.2和更新版本中,AssertionError更好)。

 类似资料:
  • 问题内容: 当我有许多可以引发异常的表达式时,例如: 有没有处理这些表达式通过某种方法 一个 功能 ,将返回一些默认值(或空)如果一个参数是无效的,并抛出一个异常-这可能发生,如果,例如: 这样我就不需要用try-catch块包围每个表达式或检查每个点是否为null。 问题答案: 用途: 这设置为链中是否有任何东西。 如果只想在非空值的情况下设置其值,请删除分配,并将其更改为:

  • 这是主要的方法: 运行时,这是堆栈跟踪:

  • 问题内容: 是否有关于对象是否使用异常的构造函数清除的详细信息。 众所周知,定义此方法的时间很短。根据手册: Java编程语言不能保证哪个线程将为任何给定对象调用finalize方法。但是,可以保证,调用finalize的线程在调用finalize时不会持有任何用户可见的同步锁。如果finalize方法抛出未捕获的异常,则该异常将被忽略,并且该对象的终止将终止。 http://docs.oracl

  • 这是我的代码: 以下是我的任务要求: 一个参数化构造函数,将接收endpoint(作为点)、方向(作为int)和样式(作为字符串)。如果接收到的点或字符串为空,则抛出新的IllegalArgumentException( 我知道我检查样式是虚线、虚线还是双精度的部分出了问题,因为当我把它注释出来时,除了那个部分,所有的东西都工作了。就现在的情况而言,它只是在所有事情上抛出了非法的辩论例外。 我有一

  • 我正在将应用程序迁移到最新的spring boot版本(使用gradle spring boot dependencies和2.5.4版)。 我有一个名为的实体,它用注释;以及另一个实体,用注释。Customer类有

  • 我有一个名为的类,它的构造函数可能会抛出。 现在我想为类实现线程安全的单例模式。通常,我通过将构造函数私有化来实现单例,创建一个与class类型相同的静态final变量,该变量也调用构造函数,然后使用getInstance方法来访问它: 问题是这种解决方案在这种情况下不起作用,因为构造函数抛出了一个检查异常。将checked exception更改为unchecked不是选项。解决办法是什么? 澄