异常

Java语言中将程序执行中发生的不正常情况称为“异常”

【开发中的语法错误和逻辑错误不是异常】

异常事件分两大类:

1)Error错误

Java虚拟机无法解决的严重问题,例如StackOverflowError(栈溢出)等等严重错误,程序会崩溃

2)Exception异常

其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理,例如NullPointerException空指针访问等等

Exception异常分为两部分,运行时异常和编译时异常

1)运行时异常,程序运行时发生的异常,是编译器不要求强制处理的异常,一般指的是编程时的逻辑错误,应该避免的错误

2)编译时异常,编程时编译器检查出的异常,是编译器要求必须处理的异常

异常与异常处理_异常处理

常见异常

常见运行时异常

1)NullPointerException空指针异常

2)ArithmeticException数字运算异常

3)ArrayIndexOutOfBoundsException数组下标越界异常

4)ClassCastException类型转换异常

5)NumberFormatException数字格式不正确

常见的编译异常

1)SQLException  操作数据库时,查询表可能发生异常

2)IOException  操作文件时,发生的异常

3)FileNotFoundException  当操作一个不存在的文件时,发生异常

4)ClassNotFoundException  加载类,而该类不存在时,异常

5)EOFException  操作文件,到文件末尾,发生异常

6)illegalArguementException  参数异常

异常处理

1)try-catch-finally

try-catch-finally在代码中捕获发生的异常,进行处理

try {
	//可能出现异常的代码
} catch (Exception e ){
 	//若捕获到异常 
  //1、当一场发生时
  //2、系统将异常封装成Exception e对象,传递给catch
  //3、得到异常对象后,程序员可以自行设置如何处理
  //4、如果没有发生异常catch代码块不执行
 
} finally {
	//无论try代码块是否有异常发生,始终要执行finally
}

注意:

1、若出现异常,没有使用try-catch语句,则默认使用throws抛出异常

2、如果异常发生,则异常发生后面的代码不会执行,直接进入到catch块

3、如果异常没有发生,则顺序执行try的代码块,不会进入到catch

4、如果没有finally,语法上也可以通过

5、可以有多个catch语句,捕捉不同的异常,要求父类异常在前,子类异常在后,且若发生异常,通常只会匹配一个

try {  // 出现一个异常后续的代码将不再执行,直接顺序跳转到catch代码块
Person person = new Person();
person.say();
int i= 10/ 0;
}catch (NullPointerException e){ // 捕捉空指针异常 --- 子类异常
  
  System.out.printin("NullPointerException");
	e.printStackTrace();
  
} catch (Exception e) { //捕捉任意异常 --- 父类异常
  
  System.out.printin("Exception");
  e.printStackTrace();
  
}finally {
System.out.println("finally);

6、可以使用try-finally的形式,相当于没有捕获异常,程序会直接崩掉

2)throws

throws将发生的异常抛出,交给调用者处理,最顶级处理者为JVM

throw手动生成异常对象的关键字,后跟异常类型

throws异常处理的一种方式,后跟异常对象

1)如果一个方法中的语句执行时可能生成某种异常,但是不确定如何处理这种异常,则此方法应显示地声明抛出异常,表示该方法不对这些异常进行处理,而由方法的调用者负责处理(try-catch)

2)在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可是它的父类

3)对于编译异常,程序必须显示处理,使用(try-catch或者throws)

4)对于运行时异常,程序中没有处理,默认使用throws的方式处理

5)子类重写父类的方法,对抛出异常的规定,异常的范围,不能比其父类范围大

class Father{
	public void say() throws RuntimeException{  //  运行时异常
  }
}
class Son extends Father{
	//情况一   ---   √
  public void say() throws ArithmeticException{  //算术异常
  }
  //情况二   ---   ×
  public void say() throws Exception{ // 异常类型 超过其父类
  }
}

练习

//练习一
class Test {
    public static int method() {
            try {
                String[] names = new String[3];//String数组
                if (names[1].equals("hi")) {//NullPointerException
                    System.out.println(names[1]);
                } else {
                    names[3] = "hello";
                }
                return 1;
            } catch (ArrayIndexOutOfBoundsException e) {
                return 2;
            } catch (NullPointerException e) {
                return 3;
            } finally {
                return 4;
            }
    }
    public static void main(String[] args){
        System.out.println(method());
    }
}
//结果:4
//练习二
class Test {
    public static int method() {
        int i = 1;
        try {
            i++;
            String[] names = new String[3];
            if (names[1].equals("tom")) {
                System.out.println(names[1]);
            } else {
                names[3] = "hspedu";
            }
            return 1;
        } catch (ArrayIndexOutOfBoundsException e) {
            return 2;
        } catch (NullPointerException e) {
            return ++i; // ++i的语句被执行,但是还需完成finally语句
        } finally {
            return ++i; //必须执行
        }
    }
    public static void main(String[] args){
        System.out.println(method());
    }
}
// 结果: 4
//练习三
class Test {
    public static int method() {
        int i = 1;
        try {
            String[] names = new String[3];
            if (names[1].equals("tom")) {
                System.out.println(names[1]);
            } else {
                names[3] = "hspedu";
            }
            return 1;
        } catch (ArrayIndexOutOfBoundsException e) {
            return 2;
        } catch (NullPointerException e) {
            return ++i;     
        } finally {
            ++i;
            System.out.println("i=" + i);
        }
    }
    public static void main(String[] args) {
        System.out.println(method());
    }
}
// 结果:i=3,2
// 返回值 --- >temp = i的值为2
// finally必须执行,i变为3
// 所以先打印finally中的值i=3
// 然后返回临时变量temp = 2
练习四
public class Test {
    public static void main(String[] args) {
        try{
            func();
            System.out.println("A");
        }
        catch(Exception e){
            System.out.println("C");
        }
        System.out.println("D");

    }
    public static void func(){
        try{
            throw new RuntimeException();
        }
        finally{
            System.out.println("B");
        }
    }
}
//BCD
//练习五
public class Test {
    public static void main(String[] args) {
        try{
            showExce();
            System.out.println("A");
        }
        catch(Exception e){
            System.out.println("B");
        }
        finally{
            System.out.println("C");
        }
        System.out.println("D");
    }
    public static void showExce() throws Exception{
        throw new Exception();
    }
}
//BCD