- 异常简介
 
错误:程序运⾏时发⽣的不被期望的事件,阻⽌了程序按照预期正常执⾏
常⻅程序错误分三类:
编译错误:新⼿最常⻅,没遵循语法规范
运⾏时错误:程序在执⾏时
逻辑错误:程序没有按照预期的逻辑顺序执⾏
Java.lang软件包中有⼀个java.lang.Throwable类,这个类是java中所有错误和异常的超类,Throwable类有两个⼦类,Error与 Exception
- Error
 
是Throwable 的⼦类,包含⼤量⼦类
出错后程序⽆法处理,如OutOfMemoryError
- Exception
 
是Throwable 的⼦类,包含⼤量⼦类
程序本身可以处理的异常,如ArrayIndexOutOfBoundException
- 异常类型
 
可查异常(编译器要求必须处置的异常):RuntimeException及其⼦类以外,其他的Exception类及其⼦类, 如 IOException和ClassNotFoundException
不可查异常(编译器不要求强制处置的异常): 包括运⾏时异常(RuntimeException与其⼦类)和错误(Error),如ArrayIndexOutOfBoundsException

- 内置异常
 
可查异常(必须要在⽅法⾥⾯捕获或者抛出)
ClassNoFoundException 应⽤程序试图加载类,找不到对应的类
IllegalAccessException 拒绝访问⼀个类的时候
NoSuchFieldExcetion 请求的变量不存在
NoSuchMethodException ⽅法不存在
不可查异常
ArrayIndexOutOfBoundsException 数组索引越界
ClassCastException 强制失败抛出异常
NullPointerException 需要对象的地⽅使⽤ null 时,抛出该异常
NumberFormatException 将字符串转换成⼀种数值类型,但该字符串不能转换为适当格式时,抛出该异常
- Throwable类核⼼⽅法
 
public String getMessage()
异常的详细信息
public Throwable getCause()
异常原因
public void printStackTrace()
打印错误的堆栈信息,即错误输出流,可以看到错误原因和所在位置
public StackTraceElement [] getStackTrace()
堆栈层次的数组,下标为0的元素代表栈顶,最后⼀个元素代表⽅法调⽤堆栈的栈底
# 如下
public class ExceptionTest {
public static void main(String [] args){
try{
int result = 25/0;
System.out.println(result);
}catch (Exception e){
String msg = e.getMessage();
StackTraceElement [] arr = e.getStackTrace();
e.printStackTrace();
}
}
}
# 控制台
java.lang.ArithmeticException: / by zero
at chapter7_2.ExceptionTest.main(ExceptionTest.java:7)
- 捕获异常
 
try{
   // 可能发⽣异常的代码
}catch(AExceptionName e){
   //出异常的时候处理
}catch(BExceptionName e){
}fianall{
 
}
try后⾯跟⼀个或多个catch块,或⼀个finally块,或两者的组合
catch 不能独⽴于 try ⽽单独存在
如果代码没有对应的异常类进⾏捕获,则默认打印异常堆栈
# 如下
public class Exceotion2Test {
    public static void main(String [] args){
            test();
    }
    public static void test(){
        try {
            Student student = new Student();
            student.setAge(-1);
        }catch (NullPointerException e){
            System.out.println("出异常了 NullPointerException");
        }catch (IllegalArgumentException e){
            System.out.println("出异常了 IllegalArgumentException");
        }
    }
}- 多重异常捕获
 
⼀个 try 代码块后⾯跟多个 catch 代码块的情况就叫多重捕获
代码中发⽣异常,异常被抛给第⼀个 catch 块, 如果不匹配则继续往下⼀个catch进⾏传递
try{
// 可能发⽣异常的代码
}catch(ExceptionName1 e1){
//出异常的时候处理
}catch(ExceptionName2 e2){
//出异常的时候处理
}
- finally关键字
 
⽤来创建在 try 代码块后⾯执⾏的代码块
finally 代码块中的代码总会被执⾏
⼀般⽤于资源回收释放等操作
try、catch和finally块有两种可能的组合:try-catch-finally或try-finally
try{
// 可能发⽣异常的代码
}catch(ExceptionName1 e1){
//出异常的时候处理
}finally{
//肯定执⾏的代码
}
try{
// 可能发⽣异常的代码
}finally{
//肯定执⾏的代码
}
# 如下
public class TestException3 {
public static void main(String [] args){
int result = divide(25,0);
System.out.println("最终结果="+result);
}
public static int divide(int num1, int num2){
try {
int result = num1/num2;
return result;
}catch (Exception e){
System.out.println("出异常");
}finally {
System.out.println("finally执行了");
return -2;
}
}
}
# 控制台
出异常
finally执行了
最终结果=-2
- throws/throw关键词
 
throws 声明异常 往外抛出
throws⼦句放在⽅法参数列表的右括号之后,⼀个⽅法可以声明抛出多个异常,多个异常之间⽤逗号隔开
# 如下方式抛出异常
public class Main {
public static void readChar() throws IOException,RemoteException {
int input = System.in.read();
}
}
try catch中捕获了异常,处理⽅法
捕获⾃⼰处理然后继续往外⾯抛异常
# 如下方式抛出异常
throw new ExceptionName("异常信息");
# 如下
public class TestException5 {
public static void main(String [] args)throws Exception{
int result = divide(25,0);
}
public static int divide(int num1, int num2)throws Exception{
try {
int result = num1/num2;
return result;
}catch (Exception e){
System.out.println("出异常了");
throw new Exception("参数异常");
}
}
}
# 控制台
出异常了
Exception in thread "main" java.lang.Exception: 参数异常
at chapter7_5.TestException5.divide(TestException5.java:15)
at chapter7_5.TestException5.main(TestException5.java:6)
- 自定义异常
 
public class UserNotEnoughException extends Exception {
    private int code;
    private String msg;
    public UserNotEnoughException(){
        super();
    }
    public UserNotEnoughException(int code, String msg){
        super(msg);
        this.code = code;
        this.msg = msg;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public int getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}
public class CustomExceptionTest {
    public static void main(String [] args){
        try{
            test();
        }catch (NullPointerException e){
            e.printStackTrace();
        }catch (UserNotEnoughException e){
          int code =  e.getCode();
          String msg = e.getMsg();
          e.printStackTrace();
          System.out.println("code="+code  + ", msg="+msg);
        }
    }
    // 抛出异常
    public static void test()throws UserNotEnoughException{
        throw new UserNotEnoughException(-1,"人员不够异常");
    }
}
# 控制台
chapter7_6.UserNotEnoughException: 人员不够异常
    at chapter7_6.CustomExceptionTest.test(CustomExceptionTest.java:22)
    at chapter7_6.CustomExceptionTest.main(CustomExceptionTest.java:10)
code=-1, msg=人员不够异常    
    










