异常处理的方式
try…..catch…..finally
格式

说明
1、  finally是个可选的,可以不写
2、  使用try将可能出现异常的代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型,在catch中进行匹配
3、  一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理
4、  处理结束后,就跳出当前的try….catch结构(在没有写finally的情况下)
5、  跳出try….catch结构,继续执行其后的代码
6、  catch中的异常类型,如果没有子父类关系,则声明顺序无所谓;若声明类型满足子父类关系,要求子类一定声明在父类的上面,否则报错
7、  在try结构中声明的变量,在出了try结构以后,就不能再被调用
8、  try….catch….finally结构可以相互嵌套
catch中常用的异常对象处理方式
- String getMessage()
public class Test {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5};
        try{
            for (int i = 0; i < arr.length  + 1; i++) {
                System.out.println(arr[i]);
            }
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
}
结果

- printStackTrace()
 (常用)
public class Test {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5};
        try{
            for (int i = 0; i < arr.length  + 1; i++) {
                System.out.println(arr[i]);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
结果

finally(可选)
- finally中声明的是一定会被执行的代码,即使catch中又出现异常或try、catch中有return语句等情况
- 使用情况
- 像数据库连接、输入输出流、网络编程Socket等资源、JVM不能自动回收的,需要自己手动的进行资源的释放,将这种操作声明在finally中
 
总结
- 使用try….catch….finally处理编译时异常,使得程序在编译时就不再报错,但是运行时仍可能报错
- 相当于我们使用这个结构将一个编译时可能出现的异常延迟到运行时出现
- 开发中由于运行时异常比较常见,所以通常不针对运行时异常编写try….catch….finally
- 针对编译时异常,一定要考虑异常处理
throws
throws + 异常类型
使用
1、  写在方法的声明处,指明此方法执行时,可能会抛出的异常类型
    
2、  当方法体执行时,出现异常,仍然会在异常代码处生成一个异常类的对象
3、  此对象满足throws后异常类型时,就会被抛出
4、  异常代码后续的代码不在执行
总结
1、  try…..catch…..finally:真正的将异常处理掉
2、  throws:只是将异常抛给方法的调用者,并没有真正的将异常处理掉
其他方式
手动抛出异常
- 关于异常对象的产生
- 系统自动生成的异常对象
- 手动生成一个异常对象并抛出(throw)
 
代码实现
public class StudentTest {
    public static void main(String[] args) {
        Student s = new Student();
        try {
            s.regist(-1001);
        } catch (Exception e) {
//            e.printStackTrace();
            System.out.println(e.getMessage());
        }
        System.out.println(s);
    }
}
class Student{
    private int id;
    public void regist(int id){
        if(id > 0){
            this.id = id;
        }else{
        //    System.out.println("您输入的值非法!");
            //手动抛出异常对象
           throw new RuntimeException("您输入的值非法!");
//            throw new Exception("您输入的值非法!");
        }
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                '}';
    }
}
运行结果

自定义异常
- 自定义的类继承于现有的异常结构
- RuntimeException(运行时异常)
- Exception(异常)
 
- 提供全局常量serialVersionUID
- 重载的构造器
代码实现
class MyException extends RuntimeException{
    static final long serialVersionUID = -7034897190745766939L;
    public MyException() {
    }
    public MyException(String message) {
        super(message);
    }
}
public class StudentTest {
    public static void main(String[] args) {
        Student s = new Student();
        try {
            s.regist(-1001);
        } catch (Exception e) {
//            e.printStackTrace();
            System.out.println(e.getMessage());
        }
        System.out.println(s);
    }
}
class Student{
    private int id;
    public void regist(int id){
        if(id > 0){
            this.id = id;
        }else{
//            System.out.println("您输入的值非法!");
            throw new MyException("不能输入负数");
        }
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                '}';
    }
}
运行结果
