java基础——异常类

什么是Java异常

异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程。Java通 过API中Throwable类的众多子类描述各种不同的异常。因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的 错误条件。当条件生成时,错误将引发异常。

   Throwable:Throwable 指定代码中可用异常传播机制通过Java 应用程序传输的任何问题的共性。
有两个重要的子类:Exception(异常)和Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。

   Error:程序无法处理的错误,表示运行程序中较严重问题。大多数错误与Coder无关,而表示代码运行时JVM出现的问题。

   Exception:程序本身可以处理的异常。

   区别:异常能被程序本身处理,错误是无法处理。

  运行时异常:RuntimeException类及其子类异常,如NullPointerException、IndexOutBoundsException等,这些异常是不检查异常,可以选择捕获处理,也可以不捕获。

  运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。

  非运行时异常:是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

处理异常机制

抛出异常:当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找处置异常的代码并执行。

捕获异常:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。

总体来说:Java规定,对于可查异常必须捕获、或者声明抛出允许忽略不可查的RuntimeException和Error

捕获异常

1、try-catch语句

关键词try后的一对大括号将一块可能发生异常的代码包起来,称为监控区域。
Java方法在运行过程中出现异常,则创建异常对象。
将异常抛出监控区域之外,由Java运行时系统试图寻找匹配的catch子句以捕获异常。
若有匹配的catch子句,则运行其异常处理代码,try-catch语句结束。
    
匹配的原则是:如果抛出的异常对象属于catch子句的异常类,
或者属于该异常类的子类,则认为生成的异常对象与catch块捕获的异常类型相匹配。
    
需要注意的是,一旦某个catch捕获到匹配的异常类型,将进入异常处理代码,
就意味着整个try-catch语句结束。其他的catch子句不再有匹配和捕获异常类型的机会。

2、try-catch-finally语句

  finally子句表示无论是否出现异常,都应当执行的内容。

阶段小结

**    try  ****块:**用于捕获异常。其后可接零个或多个catch块,
                  如果没有catch块,则必须跟一个finally块。
**  catch  ****块:**用于处理try捕获到的异常。
** finally ****块:**无论是否捕获或处理异常,finally块里的语句都会被执行。
                    当在try块或catch块中遇到return语时,finally语句块将在方法返回之前被执行。
                   在以下4种特殊情况下,finally块不会被执行:
                    1)在finally语句块中发生了异常。
                    2)在前面的代码中用了System.exit()退出程序。
                    3)程序所在的线程死亡。
                    4)关闭CPU。
  1. try-catch-finally 规则(异常处理语句的语法规则):
  1)  必须在 try 之后添加 catch 或 finally 块。try 块后可同时接 catch 和 finally 块,但至少有一个块。
  2) 必须遵循块顺序:若代码同时使用 catch 和 finally 块,则必须将 catch 块放在 try 块之后。
  3) catch 块与相应的异常类的类型相关。
  4) 一个 try 块可能有多个 catch 块。若如此,则执行第一个匹配块。即Java虚拟机会把实际抛出的异常对象依次和各个catch代码块声明的异常类型匹配,如果异常对象为某个异常类型或其子类的实例,就执行这个catch代码块,不会再执行其他的 catch代码块
  5) 可嵌套 try-catch-finally 结构。
  6) 在 try-catch-finally 结构中,可重新抛出异常。
  7) 除了下列情况,总将执行 finally 做为结束:
       JVM 过早终止(调用 System.exit(int));
       在 finally 块中抛出一个未处理的异常;
       计算机断电、失火、或遭遇病毒攻击。
  1. try、catch、finally语句块的执行顺序:
   1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;

    2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;

    3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;

 

抛出异常

  1. throws抛出异常
 如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。   
 **Throws抛出异常的规则:**
  1) 如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。
  2)必须声明方法可抛出的任何可查异常(checked exception)。即如果一个方法可能出现受可查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误
  3)仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣。
  4)调用方法必须遵循任何可查异常的处理和声明规则。若覆盖一个方法,则不能声明与覆盖方法不同的异常。声明的任何异常必须是被覆盖方法所声明异常的同类或子类。
  1. throw抛出异常
throw总是出现在函数体中,用来抛出一个Throwable类型的异常。程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块。

Throwable类中的常用方法:

getCause():返回抛出异常的原因。如果cause不存在或未知,则返回null

getMessage():返回异常的消息信息

printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段System.err的值

Java常见异常

在Java中提供了一些异常用来描述经常发生的错误,对于这些异常,有的需要程序员进行捕获处理或声明抛出,有的是由Java虚拟机自动进行捕获处理。Java中常见的异常类:

1、java.lang.IndexOutOfBoundsException 越界异常,具体两个,如下:
   java.lang.ArrayIndexOutOfBoundsException    
           数组索引越界异常。当 对数组的索引值为负数或大于等于数组大小时抛出。
   java.lang.StringIndexOutOfBoundsException
           字符串索引超出范围异常。charAt
2、java.lang.ArithmeticException    
           算术条件异常。譬如:整数除零等。    
3、java.lang.NullPointerException    
        空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。
        譬如:调用null对象的实例方法、
             访问null对象的属性、
             计算null对象的长度、
             使用throw语句抛出null等等 
4、java.lang.ClassCastException    
          类型转换异常类     
5、java.lang.IllegalArgumentException 
          非法参数异常
6、java.lang.NegativeArraySizeException  
           数组长度为负异常
7、java.lang.ArrayStoreException 
           数组中包含不兼容的值抛出的异常
8、java.lang.SecurityException 
           安全性异常




2.IOException

  IOException:操作输入流和输出流时可能出现的异常。
  EOFException   文件已结束异常
  FileNotFoundException   文件未找到异常
  • 其他
  ArrayStoreException  数组中包含不兼容的值抛出的异常
  SQLException   操作数据库异常类  
  NoSuchFieldException   字段未找到异常
  NoSuchMethodException   方法未找到抛出的异常
  NumberFormatException    字符串转换为数字抛出的异常
  IllegalAccessException  不允许访问某类异常
  InstantiationException  当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常
  ClassNotFoundException    
        找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。 

常见异常

1.IndexOutOfBoundsException下标越界异常。例如

public static void main(String[] args) {
    int a[] = new int[10];
    System.out.println(a[10]);
    System.out.println(a[-10]);
}

2.ArithmeticException算术异常,例如

public static void main(String[] args) {
    int i = 10;
    System.out.println(i/0);
}

3.ClassCastException类转换异常,例如

public static void main(String[] args) {
    Object obj = new Date();
    String str = (String) obj;
}

4.NullPointerException空指针异常,例如

public class TestException {
    public static void main(String[] args) {
        TestPerson person = new TestPerson();
        person = null;
        System.out.println(person.toString());
    }
}
class TestPerson{
    
}

异常面试题

1.Error和Exception有什么区别?

答:Error表示系统级别的错误和程序不必处理的异常,比如内存溢出。
Exception表示需要捕捉或者程序处理的异常,是一种设计和实现问题,简单来讲就是如果程序运行正常就不会发生这样的情况。

2.try{}里有一个return语句,那么紧跟在try后面的finally{}里的代码会不会执行,什么时候执行?return前还是后?

答:会执行,在方法返回调用者前执行。简单说就是不管catch是否有return,finally里的代码都会执行。

3.Java如何进行异常处理?throws、throw、try、catch、finally分别如何使用?

答:java通过面向对象的方法进行异常处理,把各种异常进行分类,并提供的接口,在java中每一个异常都是一个对象,他是Throwable的子类的实例,
java异常处理使用五个关键字:try、catch、finally、throws、throw
一般情况下是try来执行一段程序,如果系统会抛出throw一个异常类对象,就用catch来捕获,或者使用finally来处理。try-catch是知道怎么处理异常,如果不知道就使用throws抛出异常,将异常交给方法调用者处理。

4.列出你常见的运行时异常?

①.ArithmeticException算术异常,

当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。

②.ClassCastException类转换异常

当试图将对象强制转换为不是实例的子类时,抛出该异常。例如,以下代码将生成一个 ClassCastException:

Object x = new Integer(0);
System.out.println((String)x);

③.IllegalArgumentException非法参数异常

抛出的异常表明向方法传递了一个不合法或不正确的参数。

④.IndexOutOfBoundsException下标越界异常

指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。

⑤.NullPointerException空指针异常

当应用程序试图在需要对象的地方使用 null 时,抛出该异常。这种情况包括:

调用 null 对象的实例方法。
访问或修改 null 对象的字段。
将 null 作为一个数组,获得其长度。
将 null 作为一个数组,访问或修改其时间片。
将 null 作为 Throwable 值抛出。

⑥.SecurityException安全异常

由安全管理器抛出的异常,指示存在安全侵犯。

5.阐述final、finally、finalize区别?

答:final:修饰符,修饰类表明该类不能被继承,修饰方法表明该方法不能被重写,修饰变量,则必须赋值,成为常量。
finally:是异常处理try-catch的后面总要执行的代码块,可以将资源的关闭写在里面。
finalize:Object类中定义的方法,java中允许使用finalize()方法在垃圾收集器里讲对象从内存中清除出去之前做必要的工作,这个方法是有垃圾收集器在销毁对象时候调用的。

https://www.jianshu.com/p/7401a4288931?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq

https://www.jianshu.com/p/325028ea00cd?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq

猜你喜欢

转载自blog.csdn.net/qq_31758759/article/details/82217108