RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 903495
Accepted
Петровченко Иван
Петровченко Иван
Asked:2020-11-07 21:48:52 +0000 UTC2020-11-07 21:48:52 +0000 UTC 2020-11-07 21:48:52 +0000 UTC

异常和奇怪的继承

  • 772

大家好!注意到这件事: 在此处输入图像描述

众所周知,Exception 有两种类型:

  1. 已选中
  2. 未选中

问题:为什么RuntimeException(unchecked)继承自Exception类,是(checked)?

升级: 必须使用 throws 语句显式声明异常,是否声明除了 RuntimeException 和 Error 之外的所有异常,因为它们是UNCHECKED?如何理解显式声明?

java
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Best Answer
    default locale
    2020-11-08T13:26:59Z2020-11-08T13:26:59Z

    简短的回答

    来设计:

    catch(Exception e) {
        ...
    }
    

    抓到和RuntimeException。

    长答案

    @Grundy 已经解释RuntimeException说,在规范中明确说明了这个层次结构是由 Java 作者选择的,只有他们才能可靠地解释为什么选择这个选择而不是其他选择。

    我将尝试解释为什么选择的层次结构是有意义的。

    错误和异常

    让我们从远方开始。有一个基类Throwable。所有与抛出异常相关的方法都在其中定义。它的后代,什么Error,什么Exception,没有声明任何具体的方法。事实上,这是同一个类,但名称不同。

    此层次结构明确地将致命系统错误 ( Error) 与非致命异常 ( Exception) 区分开来。理论上,开发人员应该只处理异常,如果发生错误,程序应该终止。例如,这个 try 块:

    try {
        //какой-то код
    } catch(Exception e) {
        //обрабатываем исключение
    }
    

    通常会处理NullPointerException并继续工作。但是如果它发生OutOfMemoryError了,那么执行将停止并且错误将被抛出到更高的级别。

    检查异常

    Java 的开发人员做出了颇具 争议的决定,即代码必须显式处理可能发生的任何异常。那些。如果代码引用了可以引发异常的方法,则必须使用 try-catch 块显式处理它:

    try {
        //метод, который может выбросить IOException
        throwingMethod();
    } catch(IOException e) {
        //явно обрабатывается
    }
    

    或使用 throws 在调用方法中显式声明:

    //Так мы объявляем всему миру, что наш метод опасный
    //и может выбросить исключение.
    //Любой код, который вызовет метод, должен будет либо 
    //обработать исключение, либо передать дальше.
    void myMethod() throws IOException {
        throwingMethod();
    }
    

    如果您都不这样做,则代码将无法编译。

    Error- 不检查,因为,首先,Error在大多数情况下处理没有意义,其次,错误通常与任何特定方法无关(内存溢出随时可能发生)。

    未经检查的异常

    某些类型的异常可能非常普遍。例如,NullPointerException它可能在调用几乎任何非静态方法时发生:

    void method(MyClass obj) {
        //здесь может быть NPE
        obj.method();
        //и здесь может быть NPE
        obj.getField().method();
        //и здесь
        showMessage(obj.toString());
    }
    

    显式处理NullPointerException会导致非常尴尬的代码,其中包含大量try catch和throws。因此,对于此类异常,他们达成了妥协并声明了 class RuntimeException。

    (应该从哪些异常继承的问题RuntimeException是一个相当 有争议的问题。有人建议使用未经检查的异常来处理编程错误,但实际上选择可能很困难)

    RuntimeException继承自,Exception因为未经检查的异常仍然是异常,而不是错误:它可以被处理并且它始终取决于代码,而不是第三方,系统,因素。如果开发人员决定处理所有异常:

    catch(Exception e) {
        //обработка
    }
    

    ,然后得到RuntimeException。

    可以做得不同吗?是的,但有细微差别。考虑选项。

    选项 1.检查和未检查异常的不同后代类。

    可以为已检查和未检查的异常创建单独的基类:

                            Exception
            RuntimeException        CheckedException
    

    Exception但是在这种情况下,问题就出现了:它的继任者也应该是可验证的吗?如果是,那么这个类就CheckedException失去了它的意义,我们得到了现有的层次结构。如果没有,那么它就失去了意义RuntimeException。然后我们得到第二个选项

    选项 2:已检查的异常继承自未检查的异常

                            Exception (unchecked)
                            CheckedException  (checked)
    

    这样的层次结构是完全可以接受的,但是 Java 设计者决定基类应该是可验证的。这符合所选择的理念:默认情况下应检查异常,仅当难以在任何地方检查时才应取消检查。不是每个人都同意这一理念,但我们拥有我们所拥有的。

    结果

    为什么RuntimeException(unchecked)继承自Exception类,是(checked)?

    以下原因:

    • 某些类的可检查性在规范中明确说明,并且与异常类的任何属性无关。继承本质上纯粹是组织/说明性的,与属性/方法继承无关。

    • 已检查的异常是异常,而不是错误,应作为异常处理。

    • Java 设计者决定异常的基类应该是可检查的。

    • 10
  2. Grundy
    2020-11-07T23:31:26Z2020-11-07T23:31:26Z

    这在规范第 11.1.1 节中明确定义:

    RuntimeException它的所有子类统称为运行时异常类。

    未经检查的异常类是运行时异常类和错误类。

    已检查异常类是除未检查异常类之外的所有异常类。也就是说,检查的异常类都是 Throwable 的子类,除了 RuntimeException 及其子类和 Error 及其子类。


    上面在规范中明确指出checked exceptions- 这些都是 Throwable 的子类,除了RuntimeException,Error及其子类。

    也就是说,RuntimeException并且Error只是编译器的特殊情况。

    @JonSkeet答案的翻译

    • 4
  3. Komdosh
    2020-11-07T23:14:33Z2020-11-07T23:14:33Z

    RuntimeException并且Error可以不明确检查,即 它们不能被包装try-catch或方法不能throws被编译,而常规方法Exception必须由 处理try-catch或传递throws。

    void neverCompiled(){
      throw new Exception();
    }
    
    void compiled(){
     try{
      throw new Exception();
     } catch(Exception e){}
    }
    
    void compiled(){
      throw new RuntimeException();
    }
    
    class Complex {
        void compiled1() throws Exception {
          throw new Exception();
        }
    
        void compiled2() {
          try{
            compiled1();
          } catch(Exception e){}
        }
    }
    
    • 3

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5