异常的基础介绍

1、概念
  • 异常就是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序
    • 为了让程序能够正常的运行,我们可以用判断的方法解决,但是这样堵漏洞的方式有很多的弊端,并且还会让代码变得很臃肿,不仅花费了很大的精力,并且漏洞也很难堵完。
    • 为了能简单的解决异常,引入了异常处理机制,来处理程序中的异常。
    • 在处理异常的过程中,涉及到的关键词有 try catch finally throw throws
2、try-catch 以及try-catch-finally
  • try-catch语法:

    try{
        //会出现异常的代码块
    }catch(IOException e ){  //catch 捕获异常
        //异常的处理方式 
    }catch(Exception e ){
         //异常的处理方式  // 打印堆栈中的异常信息用的是:e.printStackTrace();
    }
    
    • 可以写多个catch块来捕获多种异常 ,使用多个catch块捕获异常需要注意 ,异常的顺序是从小到大 , 也就是先写子类 再写父类。
    • 虽然可以直接用一个Exception 完成所有的异常捕获,但是不推荐这样的使用方式,因为这样的程序阅读性会很差。
    • try-catch的三种出现情况:
    //1,代码正常运行,不出现异常
    try{            
        System.out.println(9 / 3);  //输出结果为3
    }catch(Exception e){
        e.printStackTrace();        //程序正常,不执行
    }
    System.out.println("程序结束。");  //执行print方法
    
    //2、try中出现异常,被catch捕捉到,catch处理异常
    try{          
        System.out.println(9 / 0);  //出现异常(java.lang.ArithmeticException)
        System.out.println("路过");  // 因为出现了异常,因此不再执行try中的代码
    }catch(ArithmeticException e){  //catch捕获到异常 ArithmeticException(算术异常 )
        e.printStackTrace();        //处理异常,程序能继续执行
    }
    System.out.println("程序结束。"); //异常被处理,,因此可以打印出来
    
    //3、try中出现异常,但是catch捕捉的异常类型不匹配
    try{
        int[] is = new int[]{12,23,12,1} ;
        for(int i = 0 ; i <= is.length ; i++){  //数组下标越界异常:
        	System.out.println(is[i]);   //java.lang.ArrayIndexOutOfBoundsException
        }
    }catch(ArithmeticException e){  //catch只能捕获到异常 ArithmeticException(算术异常 )
        e.printStackTrace();//因此,异常没有被捕捉到,也就不能处理,程序被终止,不能继续向下执行
    }
    System.out.println("程序结束。"); //不会被打印出来
    
    • 对异常处理的常用方法
      • void printStackTrace() 输出异常的堆栈信息
      • String getMessage() 返回异常信息描述字符串,是printStackTrace()输出信息的一部分
  • try-catch-finally语法

    • try-catch-finally中,try必须存在,而catch以及finally不一定都存在,但是其至少必须有一个和try搭配。
    //1、三者都在
    try{
        //会出现异常的代码块
    }catch(IOException e ){  //catch 捕获异常
        //异常的处理方式 
    }finally{
        //代码块,就是无论如何,都会执行的代码
    }
    
    //2、只有try-finally
    try {
        //代码块
    }finally {
        //必须执行的代码
    }
    
    • 总的来说,finally里面的代码,不管try里面的异常是否被处理,他都会被执行,他只在一种情况之下是不会被执行的,那就是在try代码块里面,退出了JVM虚拟机 ,退出的方法就是调用exit方法,System.exit(0),或者Runtim.getRuntim().exit(0)。

    • 当try-catch中出现return时的情况。首先,finally里面的代码肯定会执行,至于其顺序是先返回结果,还是先执行finally里面的内容,下面做一总结:

      //1、return在try中,没有异常情况:
      public static void main(String[] args){  //主函数,为了调用下面的方法
      	System.out.println(test());
      }
      public static int test() {
      	int a = 90 ;
      	try {
      		a++;     				
      		return a ;             
      	}catch(Exception e) {
      		System.err.println(e.getMessage());
      	}finally {
      		a++ ;               
      		System.out.println("finally执行了");
      	}
      	return a ;
      }
      //执行结果为:    
      //finally执行了   //在这里,如国把finally的a++放到try之中,那么就是 return ++a ; 
      //91			 //虽然finally里面的代码执行了,但是return的值是finally改变之前的值
      
      
      //2、return在try中,出现异常的情况:
      public static void main(String[] args){  //主函数,为了调用下面的方法
      	System.out.println(test());
      }
      public static int test() {
          int a = 90 ;
          try {
              a++;							//执行了a++ ,此时a为91
              System.out.println(9/0);       //这里出现了异常,因此try之中剩下的代码不会执行
              System.out.println("======");  //未执行
              return a ;					   //未执行
          }catch(ArithmeticException e) {     //捕获到异常
              System.err.println(e.getMessage()); //处理了异常
          }finally {
              a++ ;                             //执行了a++,此时的a为92
              System.out.println("finally执行了");  
          }
          return a ; 								//此时的a为92
      }
      //执行结果为:
      //  / by zero
      //  finally执行了
      //  92
      
      //3、return在try、catch之中都有,出现异常的情况:
      public static void main(String[] args){  //主函数,为了调用下面的方法
      	System.out.println(test());
      }
      public static int test() {
          int a = 90 ;
          try {
              a++;							//执行了a++ ,此时a为91
              System.out.println(9/0);       //这里出现了异常,因此try之中剩下的代码不会执行
              System.out.println("======");  //未执行
              return a ;					   //未执行
          }catch(ArithmeticException e) {     //捕获到异常
              System.err.println(e.getMessage()); //处理了异常
              a = a + 5 ;						//此时的a为96
              return a ;                  //return的值为finally改变之前的,和第一种的情况一样
          }finally {
              a++ ;                             //执行了a++,此时的a为97
              System.out.println("finally执行了");  
          }
      }
      //   / by zero
      //   finally执行了
      //   96
      
    • 总结:
      try-catch-finally中 如果try中已经return了值 那么finally中对返回值的操作不会改变返回值
      try-catch-finally中 如果try中已经return了值 但是在return之前发生了异常 最终的finally将改变返回值

3、异常的结构体系
  • 父类开始 -> 一级一级的向下
  • Object 超类
    • Throwable
      • error 仅靠程序无法处理的错误
      • Exception 异常 ,可以通过程序处理的异常
        • Checked 异常: 检查异常,必须处理的异常 ,如果不处理,编译时会报错
          • SQLException
          • ClassNotFoundException
          • 。。。等
        • RuntimeException :运行时异常,可依不被处理,编译时不会报错
          • NullPointerException
          • ArrayIndexOutOfBoundsException
          • 。。。等
4、异常的声明抛出以及自定义异常
  • 异常的声明:throws

    • 在参数列表之后,声明某个方法可能抛出的各种异常,多个异常用逗号隔开

    • 声明之后,之后调用的时候,需要继续声明异常,或者直接在main方法中声明,然后交给JVM处理

  • 异常的抛出:throw

    • 异常的抛出是在方法体之中抛出的

    • 一次只能抛出一个异常;

      public static void ma() throws ClassNotFoundException{        //该方法声明了异常
          throw new ClassNotFoundException("这是一个类未找到异常") ;  //抛出一个异常
      }           
      public static void main(String[] args) throws ClassNotFoundException{
          ma() ;   //调用有异常方法的时候,需要处理异常,用try-catch 或者 继续声明
      }  
      
  • throw以及throws的区别

    • Throw 抛出异常,在方法体之中,一次只能抛出一个异常
    • throws 声明异常,在方法参数列表之后,可以声明多个异常,异常之间用 , 隔开
  • 自定义异常:当JDK提供的异常无法满足需求的时候,我们可以通过继承Throwable、Exception、RuntimeException等这些父类来自定义异常,调用父类的构造方法来实现异常信息的打印

    public class Student {	
    	private char sex ;
    	public void setSex(char sex){
    		if(sex == '男' || sex =='女' ) {
    			this.sex = sex;
    		}else {
    			throw new SexInputException("只能输入  男   或者   女") ; //抛出异常
    		}
    	}
    	//主函数
    	public static void main(String[] args) {
    		Student student = new Student();
    		student.setSex('m');
    	}
    }
    
    //自定义的异常类  
    public class SexInputException extends RuntimeException{
    	public SexInputException(String massage) {
    		super(massage) ;
    	}
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值