zoukankan      html  css  js  c++  java
  • java-异常处理2

    一 编译时异常和运行时异常的区别

    java认为如果你的程序有问题,你应该让调用者知道.

    例如:面包,长毛了.用户去买了,用户可能会挂 .应该在面包上贴上标签(异常).

    java

    如果在函数内抛出Exception//编译失败,因为编译器在检查语法时发生了错误。

    该程序已经出现问题,Java认为这个程序本身存在隐患,
    需要捕获或者声明出来(你要么把问题处理,要么把问题标识出来让调用知道)

    1.1 抛RuntimeException不要捕获,不声明?

    不是功能本身发生的异常,而是因为比如调用者传递参数错误而导致功能运行失败。(如数组下标越界)
    这时也是问题,需要通过异常来体现,但是这个异常不要声明出来的。
    声明的目的是为了让调用者进行处理
    不声明的目的是不让调用者进行处理,就是为了让程序停止,让调用者看到现象,并进行代码的修正。★★★★★

    1.2异常分两种

    1,编译时异常:编译器会检测的异常。
    2,运行时异常:编译器不会检测的异常。不需要声明。声明也可以,如果声明了,无外乎就是让调用者给出处理方式。常见的异常

    1. ArrayIndexOutOfBoundsException
    2. IllegalArgumentException
    3. NullPointerException
    4. ClassCastException

    二 异常的声明和捕获

    2.1 声明和捕获

    声明:将问题标识出来,报告给调用者。
    如果函数内通过throw抛出了编译时异常,而捕获,那么必须通过throws进行声明,让调用者去处理。

    捕获:Java中对异常有针对性的语句进行捕获。
    语句:

    try
    {
    //需要被检测的语句。
    }
    catch(异常类 变量)//参数。
    {
    //异常的处理语句。
    }
    finally
    {
    //一定会被执行的语句。
    }
    
    */

     1.1.1声明 如果定义功能时有问题发生需要报告给调用者。可以通过在函数上使用throws关键字进行声明。

    class Demo
    {
        void show(int x)throws Exception
        {
            if(x>0)
                throw new Exception();
            else
                System.out.println("show run");
        }
    }
    
    
    class ExceptionDemo7 
    {
        public static void main(String[] args) throws Exception//throws Exception//在调用者上继续声明。 
        {
            Demo d = new Demo();
                d.show(1);//当调用了声明异常的方法时,必须有处理方式。要么捕获,要么声明。
        }
    }

     结果

    1.1.2  捕获:Java中对异常有针对性的语句进行捕获。

    try
    {
    //需要被检测的语句。
    }
    catch(异常类 变量)//参数。
    {
    //异常的处理语句。
    }
    finally
    {
    //一定会被执行的语句。
    }
    
    */

     测试 

    package test;
    
    public class Test {
    
        public static void main(String[] args)  {
            Demo d = new Demo();
            try {
                d.show(1);
            } catch (Exception e) {
                System.out.println("异常发生了");
            }//当调用了声明异常的方法时,必须有处理方式。要么捕获,要么声明。
    System.out.println("Hello World!");
    } } class Demo { void show(int x)throws Exception { if(x>0) throw new Exception(); else System.out.println("show run"); } }

     结果 

    注意:上面的结果  hello world 不会运行,而用捕获时,hello world 运行了

     2.2  异常捕获图解

     2.3 声明捕获的应用

    package test;
    
    public class Test {
    
        public static void main(String[] args)  {
            try
            {
                Person p = new Person("xiaoming",-20);
                System.out.println(p);
            }
            catch (NoAgeException ex)
            {
                System.out.println("异常啦");
            }
            
    
        }
    
    }
    
    
    class NoAgeException extends RuntimeException
    {
        /*
        为什么要定义构造函数,因为看到Java中的异常描述类中有提供对问题对象的初始化方法。
        */
        NoAgeException()
        {
            super();
        }
    
        NoAgeException(String message)
        {
            super(message);// 如果自定义异常需要异常信息,可以通过调用父类的带有字符串参数的构造函数即可。
        }
    }
    
    class Person
    {
        private String name;
        private int age;
    
        Person(String name,int age)//throws NoAgeException
        {
            //加入逻辑判断。
            if(age<0 || age>200)
            {
                throw new NoAgeException(age+",年龄数值非法");
            }
            this.name = name;
            this.age = age;
        }
        //定义Person对象对应的字符串表现形式。覆盖Object中的toString方法。
        public String toString()
        {
            return "Person[name="+name+",age="+age+"]";
        }
    }

     结果

    构造函数到底抛出这个NoAgeException是继承Exception呢?还是继承RuntimeException呢?@@@
    继承Exception,必须要throws声明,一声明就告知调用者进行捕获,一旦问题处理了调用者的程序会继续执行。
    但是如果使用到了Person对象的数据,导致都失败的。
    继承RuntimeExcpetion(用的多),不需要throws声明的,这时调用是不可能编写捕获代码的,因为调用根本就不知道有问题。
    一旦发生NoAgeException,调用者程序会停掉,并有jvm将信息显示到屏幕,让调用者看到问题,修正代码

    三 运行时异常的应用@

    /*
    描述长方形,
        属性:长和宽。
        行为:获取面积。
    
    考虑健壮性问题。
    万一长和宽的数值非法。
    描述问题,将问题封装成对象,用异常的方式来表示。
    */
    /*
    不知道要继承编译时异常还是运行时异常。
    
    */
    class NoValueException extends RuntimeException
    {
        NoValueException()
        {
            super();
        }
        NoValueException(String message)
        {
            super(message);
        }
    
    }
    
    class Rec
    {
        private int length;
        private int width;
        Rec(int length,int width)
        {
            if(length<=0 ||width<=0)
            {
                //抛出异常,但是不用声明,不需要调用者处理。就需要一旦问题发生让调用者端停止,让其修改代码。
                throw new NoValueException("长或者宽的数值非法");
            }
            this.length = length;
            this.width = width;
        }
        /**
        定义面积函数。
        */
        public int getArea()
        {
            return length*width;
        }
    
    }
    class  ExceptionTest
    {
        public static void main(String[] args) 
        {
    
            Rec r = new Rec(-3,4);
            int area = r.getArea();
            System.out.println("area="+area);
    
        
    
    
        }
    }

     四 编译时异常的应用@

    4.1 理想处理事情

    案例二:毕老师用电脑讲课。
    两个对象:
        老师:
            属性:姓名。
            行为:讲课。
        电脑:
            行为:运行。
    package test;
    
    public class Test {
    
        public static void main(String[] args)  {
            Teacher t =new Teacher("liuwang");
            t.prelect();
        }
    
    }
    class Notebook {
        void run(){
            System.out.println("电脑运行了");
        }
    }
    class Teacher {
        private String name;
        private Notebook notebook;
        Teacher (String name){
            this.name=name;
            notebook = new Notebook();
        }
        // 讲课
        public void prelect (){
            notebook.run();
            System.out.println("讲课了"+name);
        }
        
    }

     4.2 考虑异常

    考虑问题:

    • 1,电脑蓝屏-->异常。
    • 2,电脑冒烟-->异常。

    注意:

    • 调用到了声明异常的方法,在这里到底是捕获好呢?还是声明好呢?
      有具体的捕获处理方式吗?有,那就捕获,没有,那么声明。
      我可以处理,重启就可以了,重启是电脑的功能。

    1,电脑蓝屏-->异常

    下面红色的部分是变化的部分

    package test;
    
    public class Test {
    
        public static void main(String[] args)  {
            Teacher t =new Teacher("liuwang");
            t.prelect();
            System.out.println("hello world");
        }
    
    }
    class LanPingException extends Exception{
        LanPingException(){super();}
        LanPingException(String s){
            super(s);
        }
        
    } 
    class Notebook {
        int statu=1;
        void run() throws LanPingException{
            if(statu==1)
                throw new LanPingException("蓝屏了");
            System.out.println("电脑运行了");
        }
        void reset(){
            statu=0;
            System.out.println("重启了....");
        }
    }
    class Teacher {
        private String name;
        private Notebook notebook;
        Teacher (String name){
            this.name=name;
            notebook = new Notebook();
        }
        // 讲课
        public void prelect (){
            try {
                notebook.run();
            } catch (LanPingException e) {
                notebook.reset();
                //e.printStackTrace();
            }
            System.out.println("讲课了"+name);
        }
        
    }

    2,电脑冒烟-->异常
    注意:

    1. 方法上可以声明多个异常,并且需要多个catch来处理
    package test;
    
    public class Test {
    
        public static void main(String[] args)  {
            Teacher t =new Teacher("liuwang");
            t.prelect();
            System.out.println("hello world");
        }
    
    }
    class LanPingException extends Exception{
        LanPingException(){super();}
        LanPingException(String s){
            super(s);
        }
        
    } 
    
    class Notebook {
        int statu=2;
        void run() throws LanPingException, MaoYanException{
            if(statu==1)
                throw new LanPingException("蓝屏了");
            if(statu==2)
                throw new MaoYanException("冒烟了");
            System.out.println("电脑运行了");
        }
        void reset(){
            statu=0;
            System.out.println("重启了....");
        }
    }
    class Teacher {
        private String name;
        private Notebook notebook;
        Teacher (String name){
            this.name=name;
            notebook = new Notebook();
        }
        // 练习
        void lianxi(){
            System.out.println("做练习");
        }
        // 讲课
        public void prelect (){
            try {
                notebook.run();
            } catch (LanPingException e) {
                notebook.reset();
            } catch (MaoYanException e) {
                
                e.printStackTrace();
            }
            System.out.println("讲课了"+name);
        }
        
    }

     结果

    结果分析:这个结果是不正确的,明明电脑已经冒烟了但是,还在讲课

    电脑冒烟了我直接处理不了,我处理的是让学生们去做练习。然后又声明出去(电脑冒烟处理不了,去找个师傅来修)

    声明出去后,让调用讲课的知道。进行处理

    package test;
    
    public class Test {
    
        public static void main(String[] args)  {
            Teacher t =new Teacher("liuwang");
            try {
                t.prelect();
            } catch (MaoYanException e) {
                System.out.println("huanlaoshi");
                //e.printStackTrace();
            }
            System.out.println("hello world");
        }
    
    }
    class LanPingException extends Exception{
        LanPingException(){super();}
        LanPingException(String s){
            super(s);
        }
        
    } 
    
    class Notebook {
        int statu=2;
        void run() throws LanPingException, MaoYanException{
            if(statu==1)
                throw new LanPingException("蓝屏了");
            if(statu==2)
                throw new MaoYanException("冒烟了");
            System.out.println("电脑运行了");
        }
        void reset(){
            statu=0;
            System.out.println("重启了....");
        }
    }
    class Teacher {
        private String name;
        private Notebook notebook;
        Teacher (String name){
            this.name=name;
            notebook = new Notebook();
        }
        // 练习
        void lianxi(){
            System.out.println("做练习");
        }
        // 讲课
        public void prelect () throws MaoYanException{
            try {
                notebook.run();
            } catch (LanPingException e) {
                notebook.reset();
            } catch (MaoYanException e) {
                lianxi();
                //e.printStackTrace();
                throw e;
            }
            System.out.println("讲课了"+name);
        }
        
    }

    异常的转换@@

    讲课中冒烟,问题可以临时解决,是冒烟问题没有直接处理,所以就使用throws声明。
    但是发现,这个问题不应该属于讲课的问题。调用讲课方法的调用者是处理不了这个冒烟问题的。
    该调用者能处理的应该是冒烟导致的课程进行不下去的问题。
    应该在列出一个异常。课时停止异常。

    例如:储户去存钱,你是银行,你把钱存到金库里面,可是呢金库出现问题了,你的做法应该是catch (处理)金库的问题

    接下来,throw(抛出)异常说今天不能存了,不是说金库出现了什么具体的问题,直接告诉不能存了,至于金库的问题应该是你要解决的问题

    package test;
    
    public class Test {
    
        public static void main(String[] args)  {
            Teacher t =new Teacher("liuwang");
          
                try {
                    t.prelect();
                } catch (NoPlanException e) {
                    System.out.println("huanlaoshi");
                }
            
            System.out.println("hello world");
        }
    
    }
    class LanPingException extends Exception{
        LanPingException(){super();}
        LanPingException(String s){
            super(s);
        }
        
    } 
    
    class Notebook {
        int statu=2;
        void run() throws LanPingException, MaoYanException{
            if(statu==1)
                throw new LanPingException("蓝屏了");
            if(statu==2)
                throw new MaoYanException("冒烟了");
            System.out.println("电脑运行了");
        }
        void reset(){
            statu=0;
            System.out.println("重启了....");
        }
    }
    class Teacher {
        private String name;
        private Notebook notebook;
        Teacher (String name){
            this.name=name;
            notebook = new Notebook();
        }
        // 练习
        void lianxi(){
            System.out.println("做练习");
        }
        // 讲课
        public void prelect () throws NoPlanException  {
            try {
                notebook.run();
            } catch (LanPingException e) {
                notebook.reset();
            } catch (MaoYanException e) {
                lianxi();
                //e.printStackTrace();
                throw new NoPlanException("没有");
            }
            System.out.println("讲课了"+name);
        }
        
    }


    作者:8亩田
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.

    本文如对您有帮助,还请多帮 【推荐】 下此文。
    如果喜欢我的文章,请关注我的公众号
    如果有疑问,请下面留言

    学而不思则罔 思而不学则殆
  • 相关阅读:
    Solidity通过合约转ERC20代币
    各种开源协议区别
    shell脚本之函数
    shell脚本之循环和循环控制
    shell脚本之if判断以及case多分支选择
    shell脚本之数组
    shell脚本之变量
    nginx常用内置变量
    nignx配置文件详解
    nginx源码安装./configure常见参数详解
  • 原文地址:https://www.cnblogs.com/liu-wang/p/8232662.html
Copyright © 2011-2022 走看看