您的位置:首页 > 编程语言 > Java开发

Java异常

2018-12-06 16:53 113 查看

一、基本概念

  • 当出现程序无法控制的外部环境问题(用户提供的文件不存在,文件内容损坏,网络不可用…)时,Java就会用异常对象来描述。

二、异常分类

1、检查性异常:java.lang.Exception
2、运行期异常:java.lang.RuntimeException
3.、错误:java.lang.Error

1、检查性异常:

  • 程序正确,但因为外在的环境条件不满足引发。
  • 例如:用户错误及I/O问题–程序试图打开一个并不存在的远程Socket端口,或者是打开不存在的文件时。这不是程序本身的逻辑错误。
  • Java编译器强制要求处理这类异常,如果不捕获这类异常,程序将不能被编译。

2、运行期异常:

  • 这意味着程序存在bug,如数组越界、0被除、入参不满足规范等,这类异常需要更改程序来避免,Java编译器强制要求处理这类异常。

3、错误:

  • 一般很少见,Error一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。如java.lang.StackOverFlowError和Java.lang.OutOfMemoryError。对于这类错误,Java编译器不去检查他们。错误在程序中无需处理,而由运行环境处理。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和预防,遇到这样的错误,建议让程序终止。

三、异常的继承结构

  • 顶层是java.lang.Throwable类,检查性异常、运行期异常、错误都是这个类的子孙类,java.lang.Exception和java.lang.Error继承自java.lang.Throwable,而java.lang.RuntimeException继承自java.lang.Exception

四、异常处理

  1. Java中用2种方法处理异常:
    ①在发生异常的地方直接处理;
    ②将异常抛给调用者,让调用者处理。
  2. 非RuntionException一般都是外界错误(不考虑Error的情况下),其必须在当前类try{}catch语句块所捕获。
  3. Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。
  4. Error类体系描述了Java运行系统当中的内部错误以及资源耗尽的情形,Error不需要捕捉。
  5. catch语句:getMessage()不如printStackTrace()。
    ①e.getMessage(); 只会获得具体的异常名称. 比如说NullPoint 空指针,就告诉你说是空指针。
    ② e.printStackTrace();会打出详细异常,异常名称,出错位置,便于调试用,
    一般一个异常至少几十行。
  6. finally语句:如果把finally块置try…catch…语句后,finally块一般都会得到执行,它相当于一个万能的保险,即使前面的try块发生异常,而又没有对应异常的catch块,finally块将马上执行。
  7. 以下情形,finally块将不会被执行:
    1、finally块中发生了异常;
    2、程序所在的线程死亡;
    3、在前面的代码中用了System.exit();
    4、关闭CPU

五、多个异常的处理规则

  • 子类异常的处理块必需在父类异常处理块的前面,否则会发生编译错误。所以越特殊的异常越在前面处理,越普通的异常越在后面处理。这类似于制订防火墙的规则次序:较特殊的规则在前,较普通的规则在后。
    自己也可以定义并抛出异常,方法是2步:
  • 创建异常,抛出异常(首先实例化一个异常对象,然后用throw抛出)合在一起就是—throw new IOException(“异常说明信息”),将创建异常,抛出异常合在一起的好处是:创建异常时,会包含异常创建处的行信息,异常被捕获时可以通过堆栈迹(Stack Trace)的形式报告这些信息。如果在同一行代码创建和抛出异常时,对于程序的调试将非常有用。所以,throw new XXX()已经成为一个标准的异常抛出范式。在定义一个方法时,方法块中调用的方法可能会抛出异常,可用上面的throw new XXX()处理,如果不处理,那么必需在方法定义时,用throws声明这个方法全抛出的异常。
  • 默认规则:向上抛出----被调用类在运行过程中对遇到的异常一概不作处理,而是直接向上抛出,一直到最上层的调用类,调用类根据应用系统的需求和特定的异常处理规则进行处理,如向控制台输出异常堆栈信息,打印在日志文件中。用一句形象的话来说,就是谁使用,谁(最上层的调用类)处理。
  • 每个 try 块都必须至少有一个 catch 或 finally 子句。
  • 如果某个特定异常类未被任何 catch 子句处理,该异常将沿着调用栈递归地传播到下一个封闭 try 块。如果任何封闭 try 块都未捕获到异常,Java 解释器将退出,并显示错误消息和堆栈跟踪信息。

六、 Error和Exception的区别联系

  • 继承结构:Error和Exception都是继承于Throwable
  • Error和RuntimeException及其子类称为未检查异常(Unchecked exception),其它异常成为受检查异常(Checked Exception)。

七、异常在子父类覆盖中的体现

  • 子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
  • 如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
  • 如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类方法发生了异常。就必须要进行try处理。绝对不能抛。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: