zoukankan      html  css  js  c++  java
  • 编译时程序透彻理解异常并合理使用异常

    废话就不多说了,开始。。。

        对于异常(Exception)的基本应用相信大家已比拟了解了。不了解的童鞋请参见博文:

        Java异常处置机制

        其实比拟棘手的问题是什么场合用什么异常?checked异常还是runtime异常?是抛出异常还是捕获异常?

        上面举例来探讨一下这个问题;

        

        回顾异常处置机制:

        

        异常机制使程序中异常处置代码和正常业务代码分离,也就是把某些异常交给异常处置器去处置,不让JVM直接处置。

        JMV的处置方式时打印异常跟踪栈的信息,并终止程序运行,比如:

    public static void main(String[] args) {
    	System.out.println(1 / 0);	// 程序抛出java.lang.ArithmeticException: / by zero 然后程序结束。
    	... // 上面的代码没法失失落执行。
    }

        于是乎,我来捕捉一下这个异常好了:

    public static void main(String[] args) {
    	try {
    		System.out.println(1 / 0); // 如果捕捉到异常,生成对应的异常类的对象
    	}catch(ArithmeticException ae) { // 如果捕捉到异常对象,停止自定义异常处置
    		ae.printStackTrace(); // 简略的异常处置,打印异常的跟踪栈信息
    	}
    	System.out.println("main方法结束"); // 这就是异常处置代码和正常业务代码分离的利益,逻辑上清晰,并且独自处置被捕获的异常。
    }

        问,上面的异常须要被捕捉吗?算术异常.

        如果按照平凡思维来思考,程序运行时有异常退出就好了。还捕捉啥呢?还干吗分为checked异常跟runtime异常呢?

        1:捕捉异常是为了让程序独自处置被捕获的异常。

        2:辨别checked异常跟runtime异常,是为了增强程序健壮性。

        checked(知道编译时可能会有问题,我能处置,或者你来处置,最后必须处置(抛向JVM)),编译时就必须给我说清楚怎么处置。

        runtime(知道运行时可能会有问题,我违心处置就处置,你爱处置不处置),运行期出了错你负责。

        无论是哪类异常,都不一定100%发生异常,100%发生异常的代码?你会写吗?你会写编译器让你写吗?

        

        分析与解读:

        

        运行时异常意思就是:编译时没法发现只有在运行时才会出现的异常,比如NullPointerException,编译期是没法判断的。

        如果发生了问题一定是代码bug所致,至于会不会发生问题,要看什么时候程序会运行到出错的地方。

        对于运行时异常,如果知道可能会有问题,又不影响编译,那就向上抛出就好了。声明让调用者处置该运行时异常(站在设计者的角度)。

        运行时异常即使应用try...catch块停止捕捉,那也不是真正能处置失落的,下次程序执行到这又会出现异常,因为代码本身有Bug.

        如果不用异常类去描述这些异常,那程序出现异常了,岂不死翘翘了,所以说,异常的出现是为了增强程序健壮性。

        其它的runtime异常类像:IndexOuterOfBoundsException、ArithmeticException、ClassCastException

        checked异常意思就是:编译时就知道这个地方可能会出现异常,你的程序代码很安康,但是编译器知道你的代码中某个操作会出现问题,或者说你的代码中的某个操作已抛出异常了,你必须对其停止处置。

        每日一道理
    爱,有的时候不须要山盟海誓的承诺,但她一定须要细致入微的关怀与问候;爱,有的时候不须要梁祝化蝶的悲壮,但她一定须要心有灵犀的默契与投合;爱,有的时候不须要雄飞雌从的追随,但她一定须要相濡以沫的支持与懂得。

        比如FileInputStream fis = new FileInputStream("a.txt"); 此构造抛出FileNotFoundException,所以调用者必须处置该异常,否则编译不通过。

        上面的操作是通过打开一个到现实文件的连接来创建一个FileInputStream,文件会100%不存在吗?如果发生错误了肯定是在运行时吧?

        那这老家伙为何抛出编译时异常呢?!他只是觉得你必须对可能产生的异常停止捕捉罢处置了,以为你能搞定的。怎么搞看你需求。

        看一下他的构造器源码:

    public FileInputStream(String name) throws FileNotFoundException { // 他抛出了编译时异常
    	this(name != null ? new File(name) : null);
    }

        再来看一下File构造器的源码:

    public File(String pathname) {
    	if (pathname == null) { // 他抛的是运行时异常!注意是throw,不是throws。
    	    throw new NullPointerException();
    	}
    	this.path = fs.normalize(pathname);
    	this.prefixLength = fs.prefixLength(this.path);
    }

        看出问题了吗?FileInputStream构造器亦可以不处置或者捕获处置该File构造器抛出的运行时异常,但他之所以选择抛出编译时异常,是觉得须要处置并且有能力处置该异常。

        再来看InputStream类的public abstract int read() throws IOException;  read方法涉及到I/O操作,须要访问外部资源。由于外部资源不受JVM控制,

        所以有可能会出现异常,操作失败或者操作中断或者没有权限访问。对于这些可能出现的异常,不也是运行时才能出现的吗?抛出IOException,还是觉得须要处置罢了。增强程序健壮性。

        有人说他内部也没有再去调用抛出运行时异常的方法了啊?这里read方法做的是访问系统底层操作,代码不是Java写滴。

        

        透彻懂得编译时异常(checked):

        

        到底编译时异常是个啥玩意?我都没有运行程序咋还就出现异常了?别叫名字给骗了,编译时异常那就是编译错误。

        编译时异常是对运行时异常的约束。约束你对异常停止处置。真正的异常是运行时异常。编译时异常检查的还是语法错误,因为你应用关键字抛出了编译时异常类。

        

        总结:

        

        处置异常,是一门学问,异常处置的顺遂不顺遂与后期对项目的面向对象分析(OOA)是否清晰合理有直接关系。

        在这里只是对异常停止了看似易懂的描述,真正到了现实开发中,因为项目复杂度的晋升,对异常的合理处置也必须得要求很灵活。

        而这个灵活须要靠开发教训的增多而产生一种感到,感到是建立在正确的认识以后的,感到就没法像大家描述了,感到是没法用语言表达的,哈哈。

        原创文章,转载请注明出处:

        http://blog.csdn.net/thinking_in_android

    文章结束给大家分享下程序员的一些笑话语录: N多年前,JohnHein博士的一项研究表明:Mac用户平均IQ要比PC用户低15%。超过6000多的参加者接受了测试,结果清晰的显示IQ比较低的人会倾向于使用Mac。Mac用户只答对了基础问题的75%,而PC用户却高达83%。

  • 相关阅读:
    C# 操作配置文件
    C# Excel操作类
    没有找到 mspdb100.dll 的解决办法
    工厂方法模式
    .Net互操作2
    The certificate used to sign “AppName” has either expired or has been revoked. An updated certificate is required to sign and install the application解决
    手机抓包xcode自带命令行工具配合wireshark实现
    expecting SSH2_MSG_KEX_ECDH_REPLY ssh_dispatch_run_fatal问题解决
    使用ssh-keygen设置ssh无密码登录
    远程复制文件到服务器
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3076790.html
Copyright © 2011-2022 走看看