一、Java程序中错误的分类
1、编译错误:

   编译器能够检测到的错误,一般是语法错误。此时不能将源代码(.java)编译成可执行的字节码文件(.class)。

2、运行错误:

   程序运行时产生的错误,例如被0除、数组下标越界等等。

3、逻辑错误:

   这是机器本身无法检测的,需要程序员对运行结果及程序逻辑进行分析才能发现,逻辑错误可能会导致运行结果错误,有时也可能会导致运行错误。

二、Throwable类
1、Error类(错误):

   Error类则包括了一些较少发生的内部系统错误。这些错误都是严重的错误,用户程序无法进行处理,只能通知使用者关闭程序。例如内存不足、虚拟机内部错误等等。

2、Exception类(异常):

   Exception类是所有异常类的父类,包括了一些由程序本身及环境所产生的错误。应用Java的异常处理机制,异常(Exception)可以被捕获并进行相应的处理。例如数组下标越界、被0除等等。

三、异常处理机制的概念

  1、Java 对异常进行了分类,不同类型的异常分别用不同的 Java 类表示,所有异常的根类为 java.lang.Throwable
  2、Throwable下面又派生了两个子类:Error和Exception,Error表示应用程序本身无法克服和恢复的一种严重问题。Exception 表示程序还能够克服和恢复的问题,其中又分为非检查(运行)异常和检查异常,非检查异常可以避免、不强制必须处理,在运行的时候才会出现异常,只有RuntimeException类或者其子类以及子类的子类是运行异常,其他异常类都是检查异常。非检查异常例如,数组下标越界(ArrayIndexOutOfBoundsException),空指针异常
(NullPointerException)、类转换异常(ClassCastException);检查异常是运行环境的变化或异常所导致的问题,
不可避免 在编译期必须进行异常处理,否则无法通过编译。
  3、java中异常必须try…catch处理或用throws声明继续抛给上层调用方法处理。

四、异常的分类

  1、检查异常:
    (1)不可避免 在编译期必须进行异常处理,否则无法通过编译。
    (2)常见检查异常:

名字 含义
ClassNotFoundException 无法找到指定的类时发生该异常。
FileNotFoundException 访问一个不存在的文件时发生该异常。
IOException 通常的I/O错误。

  2、非检查(运行)异常:
    (1)可以避免 不强制必须处理,在运行的时候才会出现异常,只有RuntimeException类或者其子类以及子类的子类是运行异常,其他异常类都是检查异常。
    (2)常见非检查(运行)异常:

名字 含义
ArithmeticException 算术异常、如果除数为0,则发生该异常。例:int i = 12 / 0
ArrayIndexOutOfBoundsException 数组下标越界异常、数组下标越界异常。例:int[] a = { 1 }; a[1] = 2;
NullPointerException 空指针异常 对象未实例化时访问该对象,即对象为空时,任然通过对象.方法调用。则发生该异常。例:int[] a = null; a.toString();
ClassCastException 类型转换异常
Numberformatexception 表示数字格式化异常

  注意:一个方法一次只能出现一个异常。因为遇到一个异常后,程序就不会继续向下执行了。

五、异常的处理
1、throw 关键字:

   throw new ArithmeticException();手动抛出异常。

2、java异常的传递:

  异常沿着方法的调用链反方向传递。

3、java异常的处理方式:

  1、throws声明处理异常:
    (1)需要一级一级的抛异常,只会显示出异常信息,不会对异常信息进行处理,异常后面的代码不会运行。
    (2)可以一次申明多个异常,每个异常中间用,隔开即可。如下 :

public void test3()throws NullPointerException,ArithmeticException,
ArrayIndexOutOfBoundsException, ClassCastException , NumberFormat Exception {
System.out.println("----------test3 before----- ");
Scanner sc = new Scanner(System.in) ;
}

    (3)如果多个异常有公共的父类,可以用父类异常进行替换,例如上面的可以替换成下面代码:

 public void test3()throws Exception {
 System.out.println("----------test3 before----- ");
 Scanner sc = new Scanner(System.in) ;
 }

    (4)用switch循环声明多个异常的时候,必须把switch里面声明的异常全写上,或者用它们共同的父类替换:

public void test3()throws NullPointerException , Arithmeti cException,
ArrayIndexOutOfBoundsException, ClassCastException, NumberFormatException {
System. out. println("----------test3 before----- ") ;
Scanner sC = new Scanner(System.in) ;
inti=sc.nextInt();
switch (i) {
case 0 :
throw new ArithmeticException( );
case 1 :
throw new NullPointerException();
case 2 :
throw new Array IndexOutOfBoundsException( );
case 3:
throw new ClassCastException( );
case 4:
throw new NumberFormatException();
}
System. out. println("----------test3 end----- " ) ;
}

  2、try…catch捕获式处理异常:
    (1)会显示出异常信息,同时对异常信息进行处理,异常后面的代码会继续运行。
    (2)try…catch可以处理多个异常,一个try{}可以对应多个catch(),也可以在一个catch()里面写多个异常,用或:|隔开,这种方式称为muti-catch;如果出现多个异常,可以将ctrch后面的类换成这些类的父类。如下 :

try{ 
//########################
} catch (ArithmeticException e1) {                                                                     
		e1. printStackTrace( );
}catch ( NullPointerException e2) {
		e2. printStackTrace( );
}catch (Array IndexOutOfBoundsException e3) {
		e3. pr intStackTrace();
}catch (ClassCastException e4) {
		e4. printStackTrace( ) ;
}catch (NumberF ormatException e) {
		e. printStackTrace( ) ;
System. out . println("----------test3 end----- ");

try{
//#################
} catch (ArithmeticException | NullPointerException | Array IndexOutOfBoundsException
		e1. printStackTrace( ) ;
}
System. out . println("-----test3end-- ");

    (3)catch的执行前提:catch()块里面的异常只有在和try语句里面捕获到异常相匹配的时候才会执行,如果try语句块中没有匹配到对应的异常,则catch块里面的语句不会执行。

  3、try…catch…finally:
    (1)finally没有执行的两种情况:
     ① 在执行try之前已经return
     ② 在try语句块中执行System.exit(0);方法
    (2)fially的执行时机:如果try里面有返回值,则finally语句是在try的return语句执行之后,finally语句块外边最终的return结果返回到调用此方法之前执行。
  4、Final,finally, finalize三者的区别:
    (1)final:用于声明属性,方法和类,分别表示属性不可变,方法不可重写(覆盖),被其修饰的类不可继承。
    (2)finally:异常处理语句结构的一部分,表示总是执行。
    (3)finalize:Object类的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。该方法更像是一个对象生命周期的临终方法,当该方法被系统调用则代表该对象即将“死亡”,但是需要注意的是,我们主动行为上去调用该方法并不会导致该对
象“死亡”,这是一个被动的方法(其实就是回调方法),不需要我们调用。

六、方法中覆盖的异常

  1、子类重写父类方法时,重写的方法不能比被重写方法抛出更多更大的异常.
  2、重写的方法抛出的异常只能是被重写方法抛出异常的子类(可以同时写多个异常子类)或相同。

七、Message属性与异常追踪
try {
		throw new NullPointerException("这是空指针异常");
	} catch (Exception e) {
		e.printStackTrace();
	}
	******************************************
	java.lang.NullPointerException: 这是空指针异常
	at test2.Sample.main(Sample.java:27)
catch(NullPointerException e) {
x=20;
System. out. println("catch. .."+x);
e.printStackTrace();
System.err.println(e. getMessage());
}finally {
}
运行后输出:test方法中出现空指针异常
八、自定义异常

  1、场景:比如说输入密码,三次不正确的时候,抛出错误给予提示。
  2、创建检查异常:
    (1)继承Exception或除RuntimeException的其他子类。
    (2)编写构造方法,无参和有参,通过super()将异常信息传递给父类。
  3、创建运行(非检查)异常:
    (1)创建运行异常需要继承runtimeException类。
    (2)编写构造方法,通过super()将异常信息传递给父类。

public class MyCheckException extends Exception {
	public MyCheckException() {
	}
	public MyCheckException(String msg) {
		super(msg);
	}
}
	public static void test() throws MyCheckException {
		throw new MyCheckException("这是自定义的检查异常");
	}
class Test {
	public static void main(String[] args) throws MyCheckException {
		test();
	}
}
九、思维导图

Java高级----异常处理机制、自定义异常----含思维导图_父类