| 1. 什么是异常?2. Java 的异常体系 
 
 别担心,用的多了就记住啦~~
 3. 异常的分类异常分为:运行时异常 和 编译时异常 (1)运行时异常运行时异常:指程序在运行起来之后所抛出的异常,属于 非受查异常
 (2)编译时异常编译时异常:在程序编译时抛出的异常,属于 受检查异常,换句话说,这类异常在出现时,程序猿必须进行处理,否则,程序不能通过编译;
 (3)两者之间的区别运行时异常 与 编译时异常 的区别 | 编译时异常 | 运行时异常 | 
|---|
 | 发生概率高 | 一般不发生 |  | 发生之后需进行显示处理(try-catch/上报) | 不需要进行预处理 | 
 有关异常(1) 如何抛出异常?Java 中使用 throw 关键字来抛出一个异常; 如下所示:
  (2) 如何声明异常–throws使用 throws关键字, 把可能要抛出的异常显式标注在方法定义的位置,从而提醒调用者捕获这些异常 举例:  public static void testThrows() throws ArrayIndexOutOfBoundsException{
        int[] arr={1,2,3,4,5};
        System.out.println(arr[6]);
    }
 注意:  throws 须跟在方法的参数列表之后 声明的异常必须是Exception 或 Exception的子类 throws 之后可以跟多个异常类型,中间用逗号隔开,若这些异常具有继承关系,直接声明父类即可 调用者需要对异常进行处理,或者直接采用继续向上抛出 - 处理态度:上报
 (3) 如何捕获异常----try-catchtry{ 
     有可能出现异常的语句 ; 
}catch (要捕获的异常类型1  e) {
} catch (要捕获的异常类型2  e) {
}finally {
        此处代码一定会执行
}
 catch可以有多个,用来捕获不同的异常类型信息
 public class Demo01 {
    public static void method(){
        try{
            int[] array={1,2,3};
           System.out.println(array[100]);
           
           
          
        }catch(ArrayIndexOutOfBoundsException e){
            e.printStackTrace();
        }catch(NullPointerException e){
            e.printStackTrace();
        }
        finally{
            System.out.println("============");
        }
    }
    public static void main(String[] args) {
        method();
    }
}
 当执行此代码时,会有以下结果:
  当上述代码执行数组为空,并且访问数组元素是时(即  array=null;
System.out.println(array[2]);
 这两条代码时,就会产生如下所示结果: (4) 如何处理异常? 
 第一步:程序先执行 try 中的代码
  
 第二步:当 try 中的代码出现异常, 就会结束 try 中的代码, 同时,看和 catch 中的异常类型是否匹配
  
 第三步:找到匹配的异常类型, 就执行 catch 中对应的代码,没有找到与之匹配的异常类型, 就会将异常向上传递给上层调用者
  
 第四步:无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行)
  
 最后:一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序才会终止异常
 (5) finally关键字 
 finally执行的时机是在方法返回之前,但如果 finally 中存在 return 语句, 那么就会执行 finally 中的 return,而不会执行到 try 中原有的 return(建立在try-catch中也包含return语句),但finally都会执行
 (6) ErrorError:指 Java 运行时内部出现错误 或 资源耗尽错误,应用程序不会抛出此类 异常,这种内部错误一旦出现,只能终止程序;
 public class Test {
   public  static void method(){
       method();
   }
    public static void main(String[] args) {
        method();
    }
}
 类似于这种,函数自己调用自己,就会导致无限调用,此时就会抛出:
  另一种错误:
  int[] arr=new int[0x7fffffff];
 
 4. 常见的异常在之前的学习过程中,已经接触过了一些异常,常见的异常有:  
 除数为0(也叫算数异常)
   System.out.println(10/0);
 结果会抛出:  
 数组下标越界(数组下标越界异常)
   int[] arr={1,2,3,4,5};
  System.out.println(arr[6]);
 结果会抛出:  
 访问 null 对象(空指针异常)
  int[] arr=null;
System.out.println(arr[3]);
 结果会抛出: 
 5. 防御式编程程序出现问题的时候及时通知程序猿. 主要有两种主要的方式: LBYL Look Before You Leap,在操作之前做好充分的检查; 比如:小时候喜欢吃辣条,当想吃的时候,就会问妈妈:“我可不可以吃一包辣条”征求妈妈同意后,再去吃!
 EAFP It’s Easier to Ask Forgiveness than Permission.“事后获取原谅比事前获取许可更容易”. 也就是 先操作, 遇到问题再处理(
 推荐使用) 比如:还是吃辣条,这次不一样了,直接先吃一包,于是,把妈妈气哭了,然后,开始安慰妈妈并道歉;
 6. 自定义异常自定义异常一定要继承一个父类异常,一般为 Exception或RuntimeException继承 Exception的异常,称为受查异常继承 RuntimeException的异常,称为非受查异常
 举例: 
public class UserException extends RuntimeException{
    public UserException(String message) {
        super(message);
    }
}
public class PasswordException extends RuntimeException{
    public PasswordException(String message) {
        super(message);
    }
}
public class Login {
    String name = "小明";
    String password = "123456";
    public boolean loginInfo(String n, String p) {
        if (!name.equals(n)) {
            throw new UserException("用户名输入错误");
        }
        if (!password.equals(p)) {
            throw new PasswordException("密码输入有误");
        }
         return true;
}
    public static void main(String[] args) {
        Login login=new Login();
        login.loginInfo("admin","123456");
   }
}
 输出结果: 不妨试一下:用户名输入正确时的情况 以及用户名和密码均正确时的情况;
 
  |