【问题标题】:Most common checked and unchecked Java Exceptions? [closed]最常见的检查和未检查 Java 异常? [关闭]
【发布时间】:2009-08-11 21:45:51
【问题描述】:

据我了解,如果不逐一查找 API 文档,就无法找出方法抛出的异常。

既然没有选择,我想倒推研究,问你在处理时遇到的最常见的异常和运行时异常:

  • 铸造
  • 数组
  • Vector、ArrayList、HashMap等
  • IO(文件类、流、过滤器……)
  • 对象序列化
  • 线程(wait()、sleep() 等)
  • 或任何其他被视为“基本 Java”的内容

我意识到这可能是主观的和无聊的,但它是为了课堂测试,我真的不知道更好。

【问题讨论】:

  • 对于已检查的异常并非如此,一个方法定义了它可能抛出的异常。对于所有其他人(如 NPE)——好吧,他们没有被检查是有原因的。
  • 您可以使用 BCEL 或 ASM 来解析二进制文件并遍历每种方法中的代码以找到答案。

标签: java exception


【解决方案1】:

未经检查的例外列表
ArrayIndexOutOfBoundsException
ClassCastException
IllegalArgumentException
非法状态异常
空指针异常
NumberFormatException
断言错误
ExceptionInInitializerError
堆栈溢出错误
NoClassDefFoundError

检查的异常列表
异常
IOException
FileNotFoundException
解析异常
ClassNotFoundException
CloneNotSupportedException
实例化异常
中断异常
NoSuchMethodException
NoSuchFieldException

【讨论】:

  • +Throwable 为 Checked,Error 为 Unchecked 以确保完整性。
【解决方案2】:

假设以下是java.lang,除非我另有说明:

  • 铸造:ClassCastException
  • 数组:ArrayIndexOutOfBoundsException、NullPointerException
  • Collections:NullPointerException、ClassCastException(如果你没有使用自动装箱并且你搞砸了)
  • IO:java.io.IOException、java.io.FileNotFoundException、java.io.EOFException
  • 序列化:java.io.ObjectStreamException(及其子类,我懒得一一列举了)
  • 线程:InterruptedException、SecurityException、IllegalThreadStateException
  • 所有情况都可能通用:NullPointerException、IllegalArgumentException

您最好查看 Java 站点的 Package Summary 页面。这是一个:http://java.sun.com/j2se/1.4.2/docs/api/java/io/package-summary.html

【讨论】:

  • 我从来没有意识到那里确实有一个“异常摘要”。谢谢!
  • (已编辑以使例外列表可读)没问题,我只是自己偶然发现的。 “一个教,两个学”这有多棒,嗯?抱歉之前有点草率,我会尽快修改。
  • 您好,刚试了上面贴到包摘要的链接,没有解决,有人知道新位置吗?
  • java.io.ObjectStreamException 的直接已知子类:InvalidClassException、InvalidObjectException、NotActiveException、NotSerializableException、OptionalDataException、StreamCorruptedException、WriteAbortedException。 (来源:docs.oracle.com/javase/7/docs/api/java/io/…)
【解决方案3】:

NullPointerException

【讨论】:

    【解决方案4】:

    java.lang:

    1. 算术异常
    2. ArrayIndexOutOfBoundsException
    3. ClassCastException
    4. ClassNotFoundException
    5. CloneNotSupportedException
    6. IllegalArgumentExcepion
    7. IllegalMonitorStateException
    8. IllegalThreadStateException
    9. IndexOutOfBoundsException
    10. 中断异常
    11. NullPointerException
    12. NumberFormatedException

    java.util:

    1. 并发修改异常

    java.io:

    1. EOFException
    2. FileNotFoundException
    3. IOException
    4. NotSerializableException

    【讨论】:

    • #12 中的错字。没有ed。
    【解决方案5】:

    正如比尔 K 所说。检查异常很容易。如果您的 IDE/程序编辑器没有为您提供查看方法 javadocs 或签名的快速方法,您需要将其丢弃。认真的。

    未经检查的异常是另一回事。但我认为未经检查的异常的最佳策略是不要试图捕捉它们。相反,您编写代码是为了避免一开始就抛出它们。例如;

    // ... not sure if 'obj' is null
    if (obj != null) {
        obj.someMethod();
    }
    // ... not sure if 'obj' has the right type
    if (obj instanceof Foo) {
        Foo foo = (Foo) obj;
    }
    // ... not sure if 'i' is in range
    if (i >= 0 && i < array.length) {
        .... = array[i];
    }
    

    这就是我推荐这个的原因:

    • 警戒测试比抛出和捕获异常的效率要几个数量级。
    • 保护测试更具可读性...更少的代码行数。
    • 如果你捕捉到一个未经检查的异常,你永远无法确定它发生的原因是你认为的;例如:
    // obj 可能为 null ... 尝试 { obj.doSomething(); } 捕捉(NullPointerException ex){ System.err.println("obj 为空"); // 错误的!!! // NPE 可能发生在 doSomething() 内部 }
    • 如果未经检查的异常是由错误引起的,您确实需要堆栈跟踪,并且(取决于应用程序)您可能不想恢复。

    显然,您只在您对代码的理解告诉您它们是必要的地方才包含这些“警卫”检查!因此,例如,如果您知道 'obj' 应该是非 null 并且 'i' 应该在范围内,那么最好不要进行检查。如果你遗漏了太多的测试,你会得到一个异常......但这很好,因为你可以使用堆栈跟踪来找出你对代码的理解错误的原因,并可能修复潜在的错误。

    【讨论】:

      【解决方案6】:

      我想提供一个按情况分组的列表,这可能比按程序包或编程领域分组更有意义。

      意外异常

      这些是理想情况下不应该在生产中抛出的异常。你应该修复它们而不是抓住它们和stfu。

      当您测试新编写的代码时(有时会被用户意外看到)

      一旦你看到它们,它们就不会再发生了。

      • 断言错误
        • 恭喜,您编写的代码很好
        • 您应该为自己犯了这个错误感到高兴,因为少(错误)多(错误)
        • 我希望您最终不会发现您的代码是正确的并且您不小心颠倒了您的断言
      • 空指针异常
        • 你的@NotNulls 在哪里?
        • 你在使用Map.get()的返回值之前检查过吗?
      • ArrayIndexOutOfBoundsException
        • 你在使用List.get()之前检查过吗?
        • 我希望你足够了解 Java 不是 JavaScript,数组是固定大小的,你不能只是 array[array.length] = newElement
      • ClassCastException
        • 过多的仿制药对你的脑细胞有害;考虑迁移到 golang!
      • IllegalArgumentException
        • 这有时可能意味着“阅读钓鱼文档”

      而且不太可能看到,

      • IllegalMonitorStateException
        • 是的,不得不synchronized 很糟糕,但在大多数语言中都是这样的
      • CloneNotSupportedException
        • 嘿,不要使用 clone()。复制构造函数不是很酷吗?

      然后你会得到更多的 NullPointerException。

      然后...仍然是 NullPointerException? @NotNull 注释是垃圾!

      当你第 100 次测试新编写的代码时

      由于竞争条件或罕见概率而发生的异常。如果您在运行代码的前 10 次看到它们,您应该购买彩票。

      • 并发修改异常
        • ?你的synchronized在哪里
      • IllegalStateException
      • StackOverflowError(非异常)
        • 您尝试过尾递归吗?

      在编译、部署等期间

      它们通常发生在您弄乱了依赖项、使用了错误版本的库等时。

      • 联动错误
      • NoClassDefFoundError
      • java.lang.XxxNotFoundException、java.lang.NoSuchXxxException(类、方法等)
        • 请不要反思

      当你太懒时

      当您使用 @lombok.SneakyThrows 或等效项时

      • 运行时异常
      • ?扩展 RuntimeException

      预期异常

      如果他们没有被抓住,这可能意味着你也太懒了。你不能阻止他们投掷;你只需要抓住他们。

      高可能性

      这些异常很可能发生,并且应该始终专门处理(即您应该实际处理它们而不是仅仅输出错误)

      • NumberFormatException
        • 我不明白为什么这个异常会扩展 RuntimeException。

      中等可能性

      这些异常有时是由于无效的用户输入而发生的(但您应该真正验证它们,因此我将它们归类为“意外异常”),有时是由于在(非压力)测试时可能无法重现的系统约束而发生.

      • IOException 和其他 java.io.XxxException
      • 安全异常
      • 堆栈溢出异常
        • 不幸的是,转到 StackOverflow 很可能不会修复您的 StackOverflowExceptions,因为当您正在寻找 Ctrl-C 和 Ctrl-V 的内容时,您会得到更多溢出的堆栈
      • StackUnderflowException
        • 不,StackOverflow 仍然没有太大帮助
      • OutOfMemoryError
        • 希望不是内存泄漏

      【讨论】:

      • "过多的泛型对你的脑细胞有害;考虑迁移到 golang!"为什么?仅仅因为一个功能?)
      • @ddsultan 这是 golang 在不提供适当补偿功能的情况下删除泛型的双关语。
      【解决方案7】:

      如何查找 java.lang.exception 的子类,例如here

      我个人使用我自己的 TransientException 的 2 个已检查异常来处理重试可能起作用的情况。 InvalidRequestException 用于验证错误。

      【讨论】:

        【解决方案8】:

        NumberFormatException

        【讨论】:

          【解决方案9】:

          检查异常很容易,当您悬停/完成方法名称时,您的编辑器应该显示 javadocs。

          未检查通常是实际错误,甚至在 javadocs 中也不经常出现。我猜最常见的可能是 IllegalArgumentException,任何具有任何可能的无效参数组合的方法都应该抛出它。

          【讨论】:

          • 如果他使用的是文本编辑器,它不一定会在方法名称完成时显示 javadocs。 :-(
          • 我认为你的意思是 IllegalArgumentException。
          • 不要使用文本编辑器。 (相信我,我做了几十年)。这就像因为您需要更多的锻炼而让自行车轮胎中的空气排出。
          • 对于 Java,我可以理解这一点,但我主要是 Unix 上的 C/Perl 程序员,而且我几乎生活在 vim 上。 耸耸肩 我想如果你认为我的意思是完全没用的东西,比如(比如)记事本,那么我会同意你的看法。但是 vim 确实有许多有用的功能,让我可以非常快地使用它,而即使是像 Visual Studio 这样有用的名称完成功能对我来说仍然较慢,因为我必须使用鼠标进行很多操作。也许几十年后我会发现 IDE 总体上更好(不仅适用于 Java 或 C#),谁知道呢。
          • @Platinum:顺便说一下——看看你上周输入的所有代码。打印出来。拿起纸,重新开始输入。这可能需要你 10 分钟,当然不到一个小时。在记事本中,它可能需要 10% 的时间,但更可能会同样快。所以你说的可能是你一周中的几分钟非常快。一旦我开始用这些术语思考,我就不得不重新考虑很多“效率实践”(例如,你也意识到结对编程一点也不浪费,打字实际上是你工作的一部分;如果它是不再重构!)
          【解决方案10】:
          • 强制转换 - ClassCastException

          • 数组 - ArrayIndexOutOfBoundsException

          • Vector、ArrayList、HashMap 等 - 我在使用 Java 集合时很少看到异常,但偶尔会出现 ConcurrentModificationException

          • IO(文件类、流、过滤器……) - FileNotFoundException

          • 对象序列化 - ClassNotFoundException

          • 线程(wait()、sleep() 等) - 根据我的经验,线程问题通常以随机方式表现出来,而不是特定于异常。必须处理 InterruptedException 会占用大量时间,虽然我还没有看到实际抛出的异常太多。

          • 或其他任何被认为是“基本 Java”的东西 - 到目前为止,在我的经验中最常见的异常是 NullPointerException。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多