请选择 进入手机版 | 继续访问电脑版
查看: 1297|回复: 0

【Java编程】关于Java异常处理机制深入理解

[复制链接]

  离线 

 成长值: 2260

  • TA的每日心情
    开心
    4 天前
  • 签到天数: 76 天

    [LV.6]常住居民II

    346

    主题

    402

    帖子

    2452

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    2452
    发表于 2019-10-19 09:14:54 | 显示全部楼层 |阅读模式
    来源:Linux社区  作者:Linux
    Java
    异常简介:
    在程序中,错误可能产生于程序员没有预料到的各种情况,或者超出程序员可控范围的环境,例如用户的坏数据、试图打开一个不存在的文件等。为了能够及时有效地处理程序中的运行错误,Java 专门引入了异常类。


    例 1

    package ch11;
    import Java.util.Scanner;
    public class TestO1
    {
        public static void main(String[] args)
        {
            System.out.println("请输入您的选择:(1~3 之间的整数)");
            Scanner input=new Scanner(System.in);
            int num=input.nextInt();
            switch(num)
            {
                case 1:
                    System.out.println("one");
                    break;
                case 2:
                    System.out.println("two");
                    break;
                case 3:
                    System.out.println("three");
                    break;
                default:
                    System.out.println("error");
                    break;
            }
        }
    }

    正常情况下,用户会按照系统的提示输入 1~3 之间的数字。但是,如果用户没有按要求进行输入,例如输入了一个字母“a”,则程序在运行时将会发生异常,运行结果如下所示。
    异常产生的原因及使用原则:

    Java 通过面向对象的方法来处理异常。在一个方法的运行过程中,如果发生了异常,则这个方法会产生代表该异常的一个对象,并把它交给运行时的系统,运行时系统寻找相应的代码来处理这一异常。

    Java 异常强制用户考虑程序的强健性和安全性。异常处理不应用来控制程序的正常流程,其主要作用是捕获程序在运行时发生的异常并进行相应处理。编写代码处理某个方法可能出现的异常,可遵循如下三个原则:
    1.在当前方法声明中使用 try catch 语句捕获异常。
    2.一个方法被覆盖时,覆盖它的方法必须拋出相同的异常或异常的子类。
    3.如果父类抛出多个异常,则覆盖方法必须拋出那些异常的一个子集,而不能拋出新异常。
    在 Java 中所有异常类型都是内置类 java.lang.Throwable 类的子类,即 Throwable 位于异常类层次结构的顶层。Throwable 类下有两个异常分支 Exception 和 Error,如图 1 所示。


    【Java编程】关于Java异常处理机制深入理解

    【Java编程】关于Java异常处理机制深入理解
    图1 异常结构图

    运行时异常都是 RuntimeException 类及其子类异常,如 NullPointerException、IndexOutOfBoundsException 等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般由程序逻辑错误引起,程序应该从逻辑角度尽可能避免这类异常的发生。

    在java应用程序中,有两种异常处理机制:抛出异常、捕获异常。

      当一个方法出现错误引发异常时,方法创建异常对象交付运行时系统,异常对象中包含了异常类型和异常出现时程序的状态等异常信息。运行时系统负责寻找处置异常的代码并执行。
    throws 关键字和 throw 关键字在使用上的几点区别如下:
    • throws 用来声明一个方法可能抛出的所有异常信息,throw 则是指拋出的一个具体的异常类型。
    • 通常在一个方法(类)的声明处通过 throws 声明方法(类)可能拋出的异常信息,而在方法(类)内部通过 throw 声明一个具体的异常信息。
    • throws 通常不用显示地捕获异常,可由系统自动将所有捕获的异常信息抛给上级方法; throw 则需要用户自己捕获相关的异常,而后再对其进行相关包装,最后将包装后的异常信息抛出。

      当一个方法产生一个它不处理的异常时,那么就需要在该方法的头部声明这个异常,以便将该异常传递到方法的外部进行处理。可以使用 throws 关键字在方法的头部声明一个异常,其具体格式如下:
    其中,returnType 表示返回值类型,method_name 表示方法名,Exception 1,Exception2,… 表示异常类。如果有多个异常类,它们之间用逗号分隔。这些异常类可以是方法中调用了可能拋出异常的方法而产生的异常,也可以是方法体中生成并拋出的异常。
    创建一个 readFile() 方法,该方法用于读取文件内容,在读取的过程中可能会产生 IOException 异常,但是在该方法中不做任何的处理,而将可能发生的异常交给调用者处理。在 main() 方法中使用 try catch 捕获异常,并输出异常信息。代码如下:

    import java.io.FileInputStream;
    import java.io.IOException;
    public class Test04
    {
        public void readFile() throws IOException
        {
            //定义方法时声明异常
            FileInputStream file=new FileInputStream("read.txt");    //创達 FileInputStream 实例对象
            int f;
            while((f=file.read())!=-1)
            {
                System.out.println((char)f);
                f=file.read();
            }
            file.close();
        }
        public static void main(String[] args)
        {
            Throws t=new Test04();
            try
            {
                t.readFile();    //调用 readFHe()方法
            }
            catch(IOException e)
            {    //捕获异常
                System.out.println(e);
            }
        }
    }

    注意:在编写类继承代码时要注意,子类在覆盖父类带 throws 子句的方法时,子类的方法声明中的 throws 子句不能出现父类对应方法的 throws 子句中没有的异常类型,因此 throws 子句可以限制子类的行为。也就是说,子类方法拋出的异常不会超过父类定义的范围。
    throw 语句用来直接拋出一个异常,后接一个可拋出的异常类对象,其语法格式如下:
    其中,ExceptionObject 必须是 Throwable 类或其子类的对象。如果是自定义异常类,也必须是 Throwable 的直接或间接子类。例如,以下语句在编译时将会产生语法错误:
    当 throw 语句执行时,它后面的语句将不执行,此时程序转向调用者程序,寻找与之相匹配的 catch 语句,执行相应的异常处理程序。如果没有找到相匹配的 catch 语句,则再转向上一层的调用程序。这样逐层向上,直到最外层的异常处理程序终止程序并打印出调用栈情况。


    在某仓库管理系统中,要求管理员的用户名需要由 8 位以上的字母或者数字组成,不能含有其他的字符。当长度在 8 位以下时拋出异常,并显示异常信息;当字符含有非字母或者数字时,同样拋出异常,显示异常信息。代码如下:

    import java.util.Scanner;
    public class Test05
    {
        public boolean validateUserName(String username)
        {
            boolean con=false;
            if(username.length()>8)
            {    //判断用户名长度是否大于8位
                for(int i=0;i<username.length();i++)
                {
                    char ch=username.charAt(i);    //获取每一位字符
                    if((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
                    {
                        con=true;
                    }
                    else
                    {
                        con=false;
                        throw new IllegalArgumentException("用户名只能由字母和数字组成!"");
                    }
                }
            }
            else
            {
                throw new IllegalArgumentException("用户名长度必须大于 8 位!");
            }
            return con;
        }
        public static void main(String[] args)
        {
            Test05 te=new Test05();
            Scanner input=new Scanner(System.in);
            System.out.println("请输入用户名:");
            String username=input.next();
            try
            {
                boolean con=te.validateUserName(username);
                if(con)
                {
                    System.out.println("用户名输入正确!");
                }
            }
            catch(IllegalArgumentException e)
            {
                System.out.println(e);
            }
        }
    }

    运行程序,当用户输入的用户名包含非字母或者数字的字符时,程序输出异常信息,如下所示。
    当用户输入的用户名长度不够 8 位时,程序同样会输出异常信息,如下所示。
    捕获异常:
    通常使用try、catch、finally来捕获异常:
    try块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟个finally块。
    finally块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally 语句块将在方法返回之前被执行。

    1)在finally语句块中发生了异常。
    3)程序所在的线程死亡。
    try、catch、finally 语句块的执行顺序:
    2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally 语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;

    我知道答案 本帖寻求最佳答案回答被采纳后将获得系统奖励20 金钱 , 目前已有0人回答
    温馨提示:
    1、在论坛里发表的文章仅代表作者本人的观点,与本网站立场无关。
    2、论坛的所有内容都不保证其准确性,有效性,时间性。阅读本站内容因误导等因素而造成的损失本站不承担连带责任。
    3、根据二○○二年一月一日《计算机软件保护条例》规定:为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬!鉴于此,也希望大家按此说明研究软件!谢谢
    4、若因线路及非本站所能控制范围的故障导致暂停服务期间造成的一切不便与损失,论坛不负任何责任。
    5、注册会员通过任何手段和方法针对论坛进行破坏,我们有权对其行为作出处理。并保留进一步追究其责任的权利。
    6、本站所有资源来自互联网,版权归原作者所有,所有资源仅供于学习、交流研究,请于下载24小时之后删除!
    7、当您在浏览本站时,发现有您自己创作的原创资源时侵犯了您的合法资源时,请您及时联系管理员,邮箱:2550721739@qq.com,我们会及时处理!
    使用 高级模式(可批量传图、插入视频等)
    您需要登录后才可以回帖 登录 | 立即注册