zoukankan      html  css  js  c++  java
  • java基础-异常

    女神镇楼

    1、概述

        异常是一个在程序执行期间发生的事件,他中断了正在执行的程序的正常指令流。如空指针、数组溢出等。在java中,异常也作为类的实例的形式出现。当某一个方法中发生错误时,这个方法会创建一个对象,并且把他传递给正在运行的系统。这个对象就是异常对象。通过异常处理机制,可以将非正常情况下的处理代码和程序的主逻辑分离,即在编写代码主流程的同时在其他地方处理异常。

        代码示例:

    public class ExceptionFirstExpression {
        public static void main(String[] args) {
            // >> TODO try 语句中如果发生了异常(Exception),那么程序会跳转到catch语句。
            // >> TODO Java会将异常相关信息封装在一个异常类的实例中,ex是指向这个异常实例的引用
            // >> TODO "处理"最简单的方法,就是调用printStackTrace将异常信息输出到控制台
            // >> TODO catch语句执行完毕,程序会继续向下顺序执行
            try {
                int[] arr = new int[1];
                arr[1] = 9;
            } catch (Exception ex) {
    
                int abc = 999;
                ex.printStackTrace();
            }
    
            try {
                String str = "";
                str.substring(9, 10);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            System.out.println("程序执行结束");
    
        }
    }

    2、异常捕捉

        为了保证程序有效的运行,需要对程序发生的异常进行相应的处理。如果某个方法抛出异常,即可以在当前方法中进行捕捉,然后进行处理,也可以将异常向上抛出,由方法调用者进行处理。java中异常捕获结构是try、catch、finally三部分组成,其中try语句块存放的是可能发生异常的java语句,catch程序块在try语句块之后,用来激发被捕获的异常,finally是异常处理结构最后的执行部分,无论try语句块如何退出,都会执行finally语句块。

        语法如下:

    try{
        //程序代码块
    }
    catch(Exceptiontype1 e){
        // 对Exceptiontype1的处理
    }catch(Exceptiontype2 e){
        // 对Exceptiontype2的处理
    }
    ...
    finally{
        //程序块
    }

       1)try-catch语句块

        代码示例:

    public class Take {
        public static void main(String[] args) {
            try{ //try语句中包含可能出现异常的程序代码
                String str = "lili";
                System.out.println(str + "的年龄是:");
                int age = Integer.parseInt("22L");//数据类型转换
                System.out.println(age);
            }catch (Exception e){//catch语句块用来获取异常信息
                e.printStackTrace(); //输出异常性质
            }
    
            System.out.println("程序结束");
        }
    }

    实例分析:

        程序最后还是输出里“程序结束”的提示信息,没有因为异常终止。可能出现异常的代码,使用try-catch处理,当try代码块中的语句出现异常时,程序就会跳转到catch代码块中执行,执行完之后,会继续执行后面的代码,而不会执行try中发生异常的语句后面的代码。使得程序不会因为异常而影响整个程序的执行。

    public class CallerExceptionAppMain {
        public static void main(String[] args) throws MyException {
            // >> TODO catch 语句是根据异常类型匹配来捕捉相应类型的异常的。
            // >> TODO 如果类型不匹配,catch语句是不会执行的,异常会继续抛出
            // >> TODO 也就是说,catch (Throwable )会捕捉到所有的异常,包括Error,建议最多只捕捉Exception
            // >> TODO 如果catch一个其实并没有被抛出的checked exception,Java程序会报错,因为Java明确的知道这个类型的异常不会发生
            // >> TODO 如果catch一个unchecked exception,Java程序不会报错
            // >> TODO 如果throws一个其实并没有被抛出的checked exception或者unchecked exception,Java程序不会报错
            Caller1 caller1 = new Caller1();
            System.out.println("调用开始");
    
            caller1.call2Exception();
    
            System.out.println("调用结束");
        }
    }

      2)finally语句块

        完整的异常处理语句一定包含finally语句块,无论程序中有无异常发生,并且之间的try-catch无论是否顺利执行完毕,都会执行finally语句。

    public class TryCatchFinallyAppMain {
    
        private static int VAL = 0;
    
        public static void main(String[] args) {
            System.out.println(withFinally());
            System.out.println(VAL);
        }
    
        private static int withFinally() {
            int len = 0;
            try {
                String s = null;
    //            String s = "abc";
                return s.length();
            } catch (Exception ex) {
                // >> TODO 异常的处理:在有返回值的情况下,返回一个特殊的值,代表情况不对,有异常
                len = -1;
                System.out.println("执行catch里的return语句");
                return len;
            } finally {
                // >> TODO 可以认为finally语句会在方法返回后,后面的方法开始前,会在return语句后
                // >> TODO 无论是因为return结束还是因为异常结束,finally语句都会执行
                System.out.println("执行finally语句");
                // >> TODO finally里最好不要有return语句
    //            return -2;
    
                // >> TODO finally里给return用的变量值赋值没用
    //            len = -2;
    
                VAL = 999;
                System.out.println("finally语句执行完毕");
            }
        }
    
    
    }

    3、java中常见的异常

    4、自定义异常

       用户只需继承Exception类即可自定义异常类。

        自定义异常类的步骤:

        1)创建自定义异常类。

        2)在方法中通过throw关键字抛出异常对象。

        3)如果在当前抛出异常的方法中处理异常,可以使用try-catch关键字捕获并处理,否则就在方法的声明处通过throws指名要抛出的异常,让方法的调用者处理。

        4)在出现异常方法的调用者中捕获并处理。

        

        代码示例:

    public class Tran {
        //定义方法,抛出异常
        static int avg(int number1,int number2) throws MyException{
            if(number1 < 0 || number2<0){
                throw new MyException("不可使用负数");
            }
            if(number1 > 100 || number2 > 100){
                throw new MyException("数值太大了");
            }
            return (number1 + number2) /2;
        }
    
        public static void main(String[] args) {
            try{
                int result = avg(102,105);
            }catch(MyException e){
                System.out.println(e);
            }
        }
    
        private static class MyException extends Exception{
            public MyException(String ErrorMessaage){
                super(ErrorMessaage);
            }
        }
    }

    5、在方法中抛出异常

      1)使用throws关键字抛出异常

        throws关键字通常被用在声明方法时,用来指定方法可能抛出的异常,多个异常可以使用“,”分割。

       代码示例:

    public class Shoot {
        static void pop() throws NegativeArraySizeException{
            //定义方法并抛出NegativeArraySizeException异常
            int[] arr = new int[-3];
        }
        public static void main(String[] args) {
            try {
                pop();
            }catch (NegativeArraySizeException e){
                System.out.println("pop()方法抛出了异常");
            }
        }
    }

      使用throws抛出异常给上级时,如果不想处理,可以继续向上抛出,但最终要有处理该异常的代码。

       

         2)使用throw关键字抛出异常

        throw关键字通常用在方法体中,并抛出一个异常对象。程序在执行到throw时终止,他后面的语句都不执行。通过throw抛出异常后,如果想在上一级代码中捕获并处理异常,需要在抛出异常的方法中使用throws关键字在方法声明时指明要抛出的异常。如果要捕获throw抛出的异常,必须使用try-catch代码块。

        代码示例:

    public class MyException extends Throwable {
        String message;
        public MyException(String ErrorMessage){
            message = ErrorMessage;
        }
        public String getMessage(){
            return message;
        }
    }
    public class Captor {
        static int quotint(int x,int y) throws MyException{
            if(y<0){
                System.out.println("除数不能是负数");
            }
            return x/y;
        }
    
        public static void main(String[] args) {
            try{
                int result = quotint(3,-2);
            }catch (MyException e){
                System.out.println(e.getMessage());
            }catch (ArithmeticException e){
                System.out.println("除数不能为0");
            }catch (Exception e){
                System.out.println("程序发生了其他的异常");
            }
        }
    }

        实例分析:

        实例中使用了多个catch语句来捕获异常,如果将catch(Exception e) 代码块放在了最前面,将永远也调用不到他后面的代码块,所以catch语句的顺序不可调换。

    6、运行时异常

      RuntimeException异常时程序运行过程中产生的异常,java类库中每个包都定义了异常类,所有这些类都是Throwable类的子类。Throwable类派生了两个子类,分别是Exception类和Error类,Error类及其子类用来描述java运行系统中的内部错误,以及资源耗尽的错误,这类错误问题比较严重。Exception类称为非致命性类,可以通过捕获处理使程序继续执行。Exception类又根据错误发生的原因,分为RuntimeException异常和除RuntimeException之外的异常。

    7、异常的使用原则

      java强制用户去考虑程序的强健性和安全性,异常处理不应用来控制程序的正常流程,他的主要作用是捕获程序运行时发生的错误,并进行相应的处理,遵循以下原则:

        1)在当前方法声明中使用try-catch方法捕获异常

        2)当一个方法被覆盖时,覆盖他的方法必须抛出相同的异常或者异常子类

        3)如果父类抛出多个异常,则覆盖方法必须抛出那些异常的一个子集,不能抛出新异常。

    public class CallerRtExceptionAppMain {
        public static void main(String[] args) {
            Caller1 caller1 = new Caller1();
            System.out.println("调用开始");
            try {
                caller1.call2RTException();
            } catch (MyRuntimeException ex) {
                // >> TODO 错误的演示!不应该使用异常做正常处理逻辑下的跳转
                System.out.println("凌波微步收到!");
            }
            System.out.println("调用结束");
        }
    }

    8、接口中的异常

    public class ImplIntfWithEx implements IntfWithEx {
        @Override
        public void danger() throws Exception {
            // >> TODO 接口中声明了抛出异常,实现类中可以抛,也可以不抛。抛的话必须是接口声明的类或其子类
            throw new Exception("");
        }
    
        @Override
        public void safe() {
            // >> TODO 接口中没有声明抛出异常,实现类中可以抛RuntimeException,也可以不抛。
            // >> TODO 如果抛 checked exception,就会出错
            // >> TODO 可以选择catch住 checked exception,然后将它封在RuntimeException里
            // throw new Exception();
            // throw new RuntimeException();
        }
    }

  • 相关阅读:
    Flask17 Flask_Script插件的使用
    python导入模块被加横线
    MYSQL中replace into的用法
    flask通过nginx代理后base_url拿不到正确的url_scheme2016-04-14 12:31
    nginx+Gunicorn部署你的Flask项目
    浅谈flask源码之请求过程
    浅谈Flask 中的 线程局部变量 request 原理
    flask基础之jijia2模板语言进阶(三)
    Redis在windows下安装过程
    如何打开Intellij IDEA的代码提示功能/联想/自动联想
  • 原文地址:https://www.cnblogs.com/pangchunlei/p/12410249.html
Copyright © 2011-2022 走看看