【问题标题】:Why NullPointerException is a runtime exception and RemoteException not?为什么 NullPointerException 是运行时异常而 RemoteException 不是?
【发布时间】:2011-02-22 12:17:51
【问题描述】:

一个可能的原因是 NullPointerException 是运行时异常,因为每个方法都可以抛出它,所以每个方法都需要有一个“抛出 NullPointerException”,而且会很丑陋。但是 RemoteException 会发生这种情况。

并且一个可能的原因是因为 RemoteException 不是运行时异常,是告诉它客户端处理异常。但是远程环境中的每个方法都需要抛出它,所以抛出NullPointerException没有区别。

猜测?我说清楚了吗?

【问题讨论】:

  • 人们如何使用甚至没有检查异常概念的语言?你能做什么不能用另一种语言干净地完成?问题是人们认为“失败”是一种特殊情况,而不是意识到失败是常态。这类人喜欢检查异常的大型 GOTO 语句。状态测试方法?超时?啊啊啊。大巨头 GOTOs“如果 sh!t 撞到粉丝”。几乎是 Java 的特殊性,它确实不会凝聚整个 Java 社区(例如 Spring 框架对他们有很大的仇恨)。
  • Webinator,这家伙问了一个非常合理的问题。没必要吐槽。

标签: java exception runtimeexception


【解决方案1】:

我不会讨论这个决定,我只会引用 Ann Wollrath(领导 Java RMI 的设计和实现)对决定的解释。这是从 RMI-USERS 档案中的 message 中提取的(来自 1999 年 1 月的消息):

决定使 RemoteException 成为 检查异常并需要远程 列出异常的方法 throws 条款不是宗教条款。 决定取决于如何做出 分布式计算可靠。这 问题每隔一段时间就会出现一次 在我们的用户列表中。我有一个 我发布的详细回复 前一阵子。如果你在这 感兴趣的。我在里面找不到 rmi-users 存档,所以我将其包含在内 下面。

干杯,

-- 安


我想说明原因 使 RemoteException 成为选中状态 例外,而不是 运行时异常。

1) 网络不可靠

我希望他们是,但事实上, 他们不是。每个网络都有 瞬态故障。你可以内置 网络冗余,但事实是 大多数网络都没有。 Intranet 有短暂的故障,如 互联网。所以,每一个 RPC, 失败。的种类 失败可能无关紧要 与“网络”本身;如果你的 服务器用完文件描述符, 您的客户将获得连接 例外。这不是网络 失败,在网络的意义上 被打破;您的服务器位于 资源的短暂状态 饿死了。

RMI 并非旨在仅处理 全网限定案例 当单台机器崩溃时崩溃。 将考虑这样的网络 可靠,要么一切正常,要么 一切都失败了——没有 部分失败。 RMI 的目标是 更广泛的受众。

2) 无法隐藏 RPC 失败 客户

部分失败是一个事实 分布式编程;这些 失败不能隐瞒 程序。故障出现在 客户端,是否异常 检查或未检查的异常,它 仍然出现。那么,应该如何 向客户端指示失败?

3) 已检查的异常促进更多 强大的程序

曾经有一段时间,橡树和 最早的Java版本没有 检查异常。异常处理 是建议性的,这是不安全的 外面的世界。这是我们的小组(吉姆 尤其是沃尔多和我 :-) 建议有例外 由编译器检查。吉姆相当 在他的论点中有说服力,告诉 一个健壮的代码将 统治。经过一番考虑,Java 进行了改造以检查 例外。只有那些例外 没有恢复或反映 应用程序错误将被取消检查 (例如,OutOfMemoryError, NullPointerException 分别)。 世界又安全了。

想象一下 Java 工程师的惊喜 当 Java API 中出现许多异常时 和编译器从 unchecked到checked,和编译器 强制区分,他们 发现实现中的错误! 所以,处理错误的最大努力 条件,无论多么善意, 还不够好。那个编译器是 有用的东西:-)

4) RemoteException 应该被选中 异常

好的,所以回到正轨。由于一个 RemoteException 是生活中的一个事实 RPC 调用(参见#1、#2)并检查 异常迫使你写安全 代码(#3),我们认为 RemoteException 一个已检查的异常 是个好主意。写作健壮 分布式程序已经够难了, 没有编译器的帮助 你有例外。

因此,有些人可能会争辩说, RemoteException 就像一个 内存不足错误;你的程序应该 如果远程调用失败,就会摔死。 我不同意这一点。是的,在 在某些情况下,无法恢复 远程异常;但如果你是 编写可靠的分布式 程序,你的客户需要赶上 失败并适当地重试。 也许您需要联系其他人 服务器,或中止一些事务 种类。如果 RemoteException 不是 处理后,它会渗出并 让你的客户端崩溃(yuk)。

其他人说有一些 中使用的远程接口 本地案例和远程案例 案例和客户不应该 处理本地的异常 情况,所以 RemoteException 不应该 必须在 throws 子句中并且 处理它不应该是强制性的。 现在,如果我们允许远程接口 省略 RemoteException 的方法和 有一个“rmic”开关来生成存根 那会抛出一个未经检查的 RemoteException,clientno 在这件事上的选择。的决定 异常处理应保留 客户端。如果你定义一个接口 只抛出未经检查的异常 你永远不能写一个客户端 希望编译器帮助处理 那些例外。我们已经 从上面的例子可以看出 检查异常促进健壮 代码。

现在出现的另一个问题 再次是开发人员需要 只需翻译本地接口和 将它们用作远程接口。这 可能适用于一小部分情况,但 如果界面不是设计的 并发和部分故障和 考虑到呼叫延迟,协议 接口捕获的可能不是 适合在分布式中使用 案子。是否传递了足够的信息 这些操作使 操作幂等?也许,但是 很可能不会。

将 RemoteException 放在每个 throws 子句可能看起来很痛苦, 但这是写作的代价 强大的分布式应用程序。

-- 安·沃尔拉斯

【讨论】:

  • 她看起来非常确信人们没有用甚至没有检查异常概念的语言编写“健壮的分布式应用程序”[原文如此]。我想喝点她上世纪抽的东西,听起来很厉害:)
  • @Downvoter 我真的想知道为什么这个答案被否决了。即使您不同意作者的观点,我也会发布参考,而不是意见。情绪化的反对票是荒谬的。
  • 我无法想象为什么有人会对此投反对票,不管人们对检查异常的感受如何,这显然可能是您可能得到的问题的最正确答案。
  • @Webinator 这不是人们可以在没有检查异常的情况下用语言编写健壮的分布式应用程序的重点。这是因为检查异常更容易处理。我总是会选择一种简单的语言,而不是一种可能的语言。
  • +1 - 绝对是对所提问题的权威回答,并且读起来很有趣。
【解决方案2】:

NullPointerException 的潜力远大于RemoteException。任何在对象上调用方法的代码(实际上是指任何 Java 代码)都可能抛出 NullPointerException。只有 RMI 代码可以抛出 RemoteException。这是“所有代码”的一小部分。

在编写 RMI 库时,设计人员决定让客户端代码能够处理这些异常。考虑到远程代码执行的性质,我认为这是合理的。

【讨论】:

    【解决方案3】:

    我的理解是:

    • 对于可预防的事情会引发 RuntimeExceptions。
    • 对于无法预防但可以恢复的事情会引发异常
    • 对于不可预防和不可恢复的事情会引发错误。

    例如,NullPointerExceptions 总是可以避免的,因此是未经检查的异常。当出现网络故障时,可能会发生 RemoteException,在方法调用之前无法合理防止,因此需要进行检查。

    【讨论】:

    • 我认为您在列表中颠倒了“异常”和“运行时异常”。 NullPointerExceptionRuntimeException
    【解决方案4】:

    除了RemoteException 仅适用于来自java.rmijavax.rmi 包(及其子包)的代码之外,RemoteExceptionIOException 的一种类型,很像SocketException 是...以及所有@987654327 @s 是检查异常。

    【讨论】:

    • 我不会对你投反对票,但这个答案不是不成为 RuntimeException 的可能原因。 RemoteException 可能只是一种 Exception 而不是 IOExeption。 Be an IOException 是在决定被检查异常之后做出的决定。
    • Java 中处理通信的所有异常都是IOException 的子类。 IOException(以及继承自Exception 而不是RuntimeException 的任何其他类)是受检异常,因此从它继承的任何类也是受检异常。
    猜你喜欢
    • 1970-01-01
    • 2015-09-10
    • 2010-10-29
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 2011-06-06
    • 1970-01-01
    相关资源
    最近更新 更多