美文网首页Java学习笔记
coreJava_12——异常

coreJava_12——异常

作者: panda_Hi | 来源:发表于2018-09-08 13:44 被阅读64次

    /*
    承认差距,沉心静气……
    (笔者最近就要找工作了,java的框架之类的还没学好,最近可能更的不及时。忙完这阵子我会再系统的整理一下这个coreJava系列,以及一些再面试和项目中的经验跟大家分享)
    */

    简书现在竟然要求绑定微信才可以发表,考虑换地方了
    
    

    一、理解异常

    1、所有异常类的祖先类为java.lang.Throwable类。它有两个直接的子类:

    • 1、Error类:表示表示仅靠程序本身无法恢复的严重错误,比如内存溢出。
    • 2、Exception类:表示程序本身无法处理的异常。又分为运行时异常和编译时异常。
      • a.运行时异常:RuntimeException类及其子类都被称为运行时异常,这种异常的特点是Java编译器不会检查它,也就是说,当程序中 可能出现这类异常时,即使没有用try...catch语句捕获它,也没有用throws子句声明抛出它,还是会编译通过。JVM默认会将异常的名称、原因等问题输出在控制台,但同时程序中止运行。
        运行时异常主要是由于代码不严谨造成,需要修改代码。在程序调试阶段,遇到这种异常时,正确的做法是改进程序的设计和实现方式,修改程序中的错误,从而避免这种异常。捕获它并且使程序恢复运行并不是明智的办法。
      • b、编译时异常:必须进行处理的,若不处理无法通过编译。不是RuntimeException的异常都是编译时异常。当程序中可能出现这类异常时,要么用try...catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。一些常见运行时异常RuntimeException
        1.java.lang.ArithmeticException 算术异常如:除0;
        2.java.lang.NullPointerException空指针引用 如:没初始化一个References便使用; 3.java.lang.ArrayIndexoutofBoundsException
        数组越界 如:调用一个有十个元素的Array的第十一个元素的内容 4.java.lang.ClassCastException 强制类型转换异常
        5.java.lang.NumberFormatException
        数据格式异常 如:Integer.parseInt("a");
        6.java.lang.NegativeArraySizeException 数组长度为负数异常

    2、通过例子可以更好的理解

    某天天气很好,小明骑车去山里游玩

    • 问题1:山路塌陷了,小明及时停住,但是无法通过了。(严重问题Error)
    • 问题2:小明出门推自行车,发现轮胎没气了。小明,重新打好气。(运行期就应该检查问题并处理)
    • 问题3:小明骑车在路上行驶着,山路两边有石子,但是中间时平坦的;
      一直在平坦的路上时没有问题的,但是小明偏喜欢骑到石子上,结果爆胎,出现问题。

    3、异常声明和处理——try...catch

    --格式:
    try{
    可能出现问题的代码
    }catch(异常名 变量名){
    针对问题的处理
    }
    catch(异常名 变量名){
    针对问题的处理
    }

    • 1.自己主动使用throw语句的时候代码会抛出异常;

    • 2.使用try-catch-finally语句结构处理或
      在方法声明上声明throws继续抛出;
      (注意:a、try中的语句越少越好 b、catch中必须有内容,用于处理以及提示等。)

      异常处理语句的语法规则:
      1.try代码块不能脱离catch代码块或finally代码块而单独存在。try代码块后面至少有一个catch代码块或finally代码块。
      2.try代码块后面可以有零个或多个catch代码块,还可以有零个或至多一个finally代码块。如果catch代码块和finally代码块并存,finally代码块必须在catch代码块后面。
      3.try代码块后面可以只跟finally代码块。
      4.在try代码块中定义的变量的作用域为try代码块,在catch代码块和finally代码块中不能访问该变量。
      5.可以有多个catch语句时,注意一但try中出现问题,将会与后边的catch里的问题进行匹配,一旦有符合的,则执行该catch里的处理语句,并结束当前try...catch,继续执行后边的程序。
      (注意:catch中的异常为平级,那么先后顺序不影响,只匹配符合的,但是若时子父关系,那么,父必须放在后边,否则,匹配到父后,即不再匹配后边其他的catch语句)
      6.如果一个方法可能出现编译异常,要么用try...catch语句捕获,要么用throws子句声明将它抛出。
      7.throw语句后面不允许紧跟其它语句,因为这些语句永远不会被执行。

    4、异常声明和处理——throws和throw

    • 1、throws
      定义功能方法时,需要把出现的问题暴露出来让调用者处理,那么就通过throws在方法上标识。
      格式:
      method() throws 异常名1,异常名2...
      编译期间异常抛出,将来调用必须处理,不 处理无法通过编译;
      运行时异常抛出,将来调用可以不处理。
    • 2、throw
      在功能方法内部出现某种情况,程序不能运行,需要进行跳转时,就要用throw抛出异常的对象(注意不是异常名)

    5、throws与throw区别(面试中常见):

    throws
    • 用在方法声明后面,跟的是异常类名
    • 可以跟多个异常类名,用逗号隔开
    • 表示抛出异常,有该方法的调用者来处理
    • throws表示出现异常的一种可能性,并不一定会发生这些异常
    throw
    • 用在方法体内,跟的是异常对象名
    • 只能抛出一个异常对象名
    • 表示抛出异常,由方法体内的语句处理
    • throw是抛出了异常,执行throw一定是抛出某种异常
    例:
    public class ExceptionDemo1 {
    
        public static void main(String[] args) {
            ExceptionDemo1 ed = new ExceptionDemo1();
            try {
                ed.method2();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("已处理异常...");
            }
    
        }
    
        public void method2() throws Exception {    //throws是用在方法声明后边
            int a = 10;
            int b = 0;
            if (b == 0) {
                // throw ArithmeticException; //错误写法,throw抛出的不是名称
                throw new Exception();// 抛出异常对象
            } else {
                System.out.println(a / b);
    
            }
        }
    }
    

    5、异常处理原则

    如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,这时用throws。
    区别:后续程序需要继续运行,就用try;反之,则用throws。

    6、finally

    • 1、finally的特点
      • finally的语句块一定执行
      • 特殊情况,在执行到finally之前JVM已经退出(比如System.exit(0))
    • 2、finally的作用
      • 用于释放资源,在IO操作和数据库中会见到
    • 3、finally相关的面试题
      • 1、final,finally和finalize的区别
        • final:最终的意思,可以修饰类(时,类不能被继承)、成员变量(时,变量就是常量)、成员方法(时,方法不能被重写)。
        • finally:是异常处理的一部分用于释放资源。一般情况,代码肯定会执行,特殊情况,在执行到finally之前jvm就退出的话将不执行。
        • finalize:是Object类的一个方法,用于垃圾回收。
      • 2、如果catch里面有return语句,请问finally的代码还会执行吗?如果会,请问是在return前还是后?
        • 会执行,在return前。
          • 准确的说,在中间。
    public class FinallyDemo2 {
        private static int a=0;
        public static void main(String[] args) {
            System.out.println(TestTheReturn());//输出30
            System.out.println("the current value of a is: "+ a);//输出40
        }
        public static int TestTheReturn() {
            a = 10;
            try {
                System.out.println(a/0);
                a = 20;
            } catch (ArithmeticException e) {
                a = 30;
                return a;//#1
                //return a执行到这里,不是return a了,而是return 30,这个返回路径已经形成
                //但是发现后边还有finally语句,因此执行finally语句的内容,a=40,
                //返回到原来的路径,继续执行return 30。
            }finally {
                a = 40;
                //return a; //#2
            }
            return a;//与#2处的return不能同时存在,跟该语句地位相同,冲突。
            //对#1处而言,已经有返回了;所以此处return语句并不执行
        }
    }
    
    

    7、自定义异常

    有些异常,Java中没有对应的异常,需要我们自定义来进行相关的异常处理。如,检查用户输入是否符合要求等。
    自定义异常分为两种

    • 继承自Exception 编译时异常——编译要检查

    • 继承自RuntimeException 运行时异常——编译不需要检查

      1、
      下面给出三个类:

    //自定义异常类
    package exception;
    //也可以是继承自RuntimeException
    //public class MyException extends RuntimeException
    public class MyException extends Exception{
        //提供构造方法,用于逐层向上传递提示信息,message
        //可通过查看api参考写法。
        public MyException() {
        }
        public MyException(String message) {
            super(message);
        }
    }
    
    //检查异常类
    package exception;
    
    public class Teacher {
        public void check(int score) throws MyException {
    
            if (score > 100 || score < 0) {
                throw new MyException("分数必须在0——100之间");
            }else {
                System.out.println("分数没有问题");
            }
        }
    
    }
    
    //测试类
    package exception;
    
    import java.util.Scanner;
    
    public class Student {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入成绩:");
            int score = scanner.nextInt();
            
            Teacher t = new Teacher();
            try {
                t.check(score);
            } catch (MyException e) {
                e.printStackTrace();
            }
        }
    }
    

    8、小结一下

    异常的注意事项

    • 子类重写父类方法时,子类的方法必须抛出相同的异常或者弗雷异常的子类。
    • 如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者时他的子类,子类不能抛出父类没有的异常。
    • 如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类的方法内有异常发生,那么子类就只能try,不能throws

    相关文章

      网友评论

        本文标题:coreJava_12——异常

        本文链接:https://www.haomeiwen.com/subject/sabkwftx.html