Exception和Error有什么区别

3,268 阅读7分钟

Exception和Error有什么区别 Exception和Error有什么区别

基本回答

共同点:

都继承了Throwable类,在Java中,只有Throwable或其子类才能被抛出(throw)或者被捕获(catch)

不同点:
  • Error:在正常情况下,不太可能出现的问题。绝大部分Error都会导致程序本身(比如JVM)出现不可避免的,不可恢复的状态。所以这样的问题也没有在程序中进行处理的必要。
  • Exception:程序正常运行中,可以预料的意外情况。这部分问题被称为异常,大部分是程序员在程序中能够解决的。在异常下面还分为检查异常和运行时异常。
  • 检查异常(checked excepttion): 这一部分异常是应该被处理掉的,如果程序中没有处理的话,编译不会通过。这类异常有两种处理方式,一是利用try-catch语法来处理,另一种是继续向上一级调用层级抛出(throws)该类异常。继承Exception就可以定义一个检查异常类。例:IOException,FileNotFoundException,SQLException,ClassNotFoundException,FileAlreadyExistsException,CloneNotSupportedException
  • 运行时异常(RuntimeException): 这一部分异常编译器不会强制让开发者处理。但这一类异常最好在合适的地方声明(throw),这样,当程序出现问题的时候就可以准确的定位了。继承RuntimeException就能定义一个运行时异常。例:ClassCastException,NullPointerException,IndexOutOfBoundsException,ConcurrentModificationException

处理异常的方式:

  1. 上一级调用层级抛出(throws):让处理这个问题的逻辑放在了上一层,在程序设计中如果分有多个模块或者层级关系,通过这种方式是很有必要的,但是不能什么都让上一级调用层处理,应该自己处理的就一定要在自己程序中处理;
  2. try-catch语法: 通常一个异常出现了,该线程会随着异常调用栈死掉,而try-catch语法的目的就是不让程序在这个地方就死掉,或者说程序有能力再往下执行,并且该异常的发生不影响业务逻辑的进行,就应该让它执行下去。

tips: 一般来说,当程序执行到某一步的时候,如果满足了异常定义的条件,便会在这个时候生成一个异常对象,这个异常对象会终止当前的线程


如何使用Exception(异常)

  1. 尽量不要 catch (Exception)或catch(Throwable)这样操作,catch特定的异常将会返回更丰富的信息。并且,catch 大异常通常是没有保证程序有能力往下执行(出现了OOM,程序并不能处理这样的问题),或者没有保证该异常的发生是不影响业务逻辑的进行的。
  2. 我们要保证程序不会捕获我们不希望捕获的异常。例:RuntimeException应该被扩散出来,而不是被捕获。
  3. 不要生吞(swallow)异常,也就是捕获了异常,不要不管了;
  4. 产品中,printStackTrace()方法更多的应该输出向日志中,而不是程序中直接打印出来;
  5. throw early,catch late原则。出现的异常应该尽早的抛出,这样方便定位;应该在尽可能靠近异常发生的位置处理异常,或者向上一级抛出;
  6. 在保证诊断信息足够的情况下,应该尽可能的避免输出敏感信息(用户个人信息);

checked exception的争议

  1. 检查异常是假设我们捕获了异常,然后恢复程序;不过在实际开发中,这样的情况几乎不会发生;现在对其的使用已经偏离了设计时的目的了;
  2. 检查异常不支持函数式编程;

异常对性能的影响

  1. try-catch语法会影响JVM对代码的优化,所以,try-catch的代码块应该覆盖得少一下为好;
  2. 虽然try-catch方式可以做一些逻辑处理,但是从性能角度看,尽量不要这么做;
  3. Java每实例化一个Exception就会对当前栈产生一个快照,这是一个相对繁重的操作; 基本回答 共同点: 都继承了Throwable类,在Java中,只有Throwable或其子类才能被抛出(throw)或者被捕获(catch)

不同点: Error:在正常情况下,不太可能出现的问题。绝大部分Error都会导致程序本身(比如JVM)出现不可避免的,不可恢复的状态。所以这样的问题也没有在程序中进行处理的必要。 Exception:程序正常运行中,可以预料的意外情况。这部分问题被称为异常,大部分是程序员在程序中能够解决的。在异常下面还分为检查异常和运行时异常。 检查异常(checked excepttion): 这一部分异常是应该被处理掉的,如果程序中没有处理的话,编译不会通过。这类异常有两种处理方式,一是利用try-catch语法来处理,另一种是继续向上一级调用层级抛出(throws)该类异常。继承Exception就可以定义一个检查异常类。例:IOException,FileNotFoundException,SQLException,ClassNotFoundException,FileAlreadyExistsException,CloneNotSupportedException 运行时异常(RuntimeException): 这一部分异常编译器不会强制让开发者处理。但这一类异常最好在合适的地方声明(throw),这样,当程序出现问题的时候就可以准确的定位了。继承RuntimeException就能定义一个运行时异常。例:ClassCastException,NullPointerException,IndexOutOfBoundsException,ConcurrentModificationException 处理异常的方式:

上一级调用层级抛出(throws):让处理这个问题的逻辑放在了上一层,在程序设计中如果分有多个模块或者层级关系,通过这种方式是很有必要的,但是不能什么都让上一级调用层处理,应该自己处理的就一定要在自己程序中处理; try-catch语法: 通常一个异常出现了,该线程会随着异常调用栈死掉,而try-catch语法的目的就是不让程序在这个地方就死掉,或者说程序有能力再往下执行,并且该异常的发生不影响业务逻辑的进行,就应该让它执行下去。 tips: 一般来说,当程序执行到某一步的时候,如果满足了异常定义的条件,便会在这个时候生成一个异常对象,这个异常对象会终止当前的线程

如何使用Exception(异常) 尽量不要 catch (Exception)或catch(Throwable)这样操作,catch特定的异常将会返回更丰富的信息。并且,catch 大异常通常是没有保证程序有能力往下执行(出现了OOM,程序并不能处理这样的问题),或者没有保证该异常的发生是不影响业务逻辑的进行的。 我们要保证程序不会捕获我们不希望捕获的异常。例:RuntimeException应该被扩散出来,而不是被捕获。 不要生吞(swallow)异常,也就是捕获了异常,不要不管了; 产品中,printStackTrace()方法更多的应该输出向日志中,而不是程序中直接打印出来; throw early,catch late原则。出现的异常应该尽早的抛出,这样方便定位;应该在尽可能靠近异常发生的位置处理异常,或者向上一级抛出; 在保证诊断信息足够的情况下,应该尽可能的避免输出敏感信息(用户个人信息); checked exception的争议 检查异常是假设我们捕获了异常,然后恢复程序;不过在实际开发中,这样的情况几乎不会发生;现在对其的使用已经偏离了设计时的目的了; 检查异常不支持函数式编程; 异常对性能的影响 try-catch语法会影响JVM对代码的优化,所以,try-catch的代码块应该覆盖得少一下为好; 虽然try-catch方式可以做一些逻辑处理,但是从性能角度看,尽量不要这么做; Java每实例化一个Exception就会对当前栈产生一个快照,这是一个相对繁重的操作; Markdown 1771 bytes 61 words 29 lines Ln 1, Col 0 HTML 1644 characters 37 words 27 paragraphs