`
winie
  • 浏览: 224313 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

Java语法总结 - 异常

    博客分类:
  • java
阅读更多
软件开发中一个古老的说法是:80%的工作使用20%的时间。80%是指检查和处理错误所付出的努力。在许多语言中,编写检查和处理错误的程序代码很乏味,并使应用程序代码变得冗长。原因之一就是它们的错误处理方式不是语言的一部分。尽管如此,错误检测和处理仍然是任何健壮应用程序最重要的组成部分。

Java提供了一种很好的机制,用强制规定的形式来消除错误处理过程中随心所欲的因素:异常处理。它的优秀之处在于不用编写特殊代码检测返回值就能很容易地检测错误。而且它让我们把异常处理代码明确地与异常产生代码分开,代码变得更有条理。异常处理也是Java中唯一正式的错误报告机制。

第一部分    异常

1、抛出异常。所有的标准异常类都有两个构造器:一个是缺省构造器,一个是带参数的构造器,以便把相关信息放入异常对象中。
    throw new NullPointerException();
    throw new NullPointerException("t = null");

2、如果有一个或者多个catch块,则它们必须紧跟在try块之后,而且这些catch块必须互相紧跟着,不能有其他任何代码。C++没有这样的限制,所以C++的异常处理处理不好就会写得很乱,抛来拋去的。

3、使用try块把可能出现异常的代码包含在其中,这么做的好处是:处理某种指定的异常的代码,只需编写一次。作业没写完的同学到走廊罚站去,这符合我们处理问题的方式,不用挨个地告诉。

4、无论是否抛出异常,finally块封装的代码总能够在try块之后的某点执行。
例子:
    try {
        return ;   
    }
    finally{
        System.out.print("You can't jump out of my hand!");   
    }

甚至你在try块内用return语句想跳过去都不可以!finally内的输出语句还是执行了!别想逃出我的手掌心!

5、catch块和finally块是可选的,你可以只使用try。但是这么做有意思吗?

6、推卸责任。Java允许你推卸责任,没有必要从相应的try块为每个可能的异常都编写catch子句。Java2类库中很多方法都会抛出异常,就是是把异常处理的权限交给了我们用户。毕竟,Java不知道你的自行车被偷了之后,你会去报案还是会忍气吞声自认倒霉,或者偷别人的自行车。我们需要这种处理异常的自由度。

7、调用栈。调用栈是程序执行以访问当前方法的方法链。被调用的最后一个方法在栈的顶部,它将被最先执行完毕,然后弹出;第一个调用方法位于底部,也就是 main函数。在catch子句中使用printStackTrace()方法打调用栈信息是比较常用的定位异常的方法。printStackTrace ()继承自Throwable。

8、异常的传播。在一个方法A中,如果一个异常没有得到处理,它就会被自动抛到调用A方法的B方法中。如果B方法也没有处理这个异常,他就会被继续依次向上抛,直到main方法。如果main也没有理会它,那么异常将导致JVM停止,程序就中止了。你被同学揍了,先去告诉老师。老师不理你你就去告诉教导处主任,教导处主任也不管那只能告诉校长,校长还不管!没有比他更大的了,于是你崩溃了,学业中止了……下面这段程序记录了悲惨的辍学历史:
    class ExceptionDemo {
        static void student() throws Exception{
            teacher();
        }
        static void teacher() throws Exception{
            schoolmaster();
        }
        static void schoolmaster() throws Exception{
            throw new Exception();
        }
        public static void main(String[] args) {
            try {
            student();
        }
        catch (Exception e) {
            e.printStackTrace();
        }        
        }
    }
输出结果是:
java.lang.Exception
    at ExceptionDemo.schoolmaster(ExceptionDemo.java:9)
    at ExceptionDemo.teacher(ExceptionDemo.java:6)
    at ExceptionDemo.student(ExceptionDemo.java:3)
    at ExceptionDemo.main(ExceptionDemo.java:13)
可以看出函数的调用栈,一级一级地哭诉……

9、异常的层次结构及Error。
        Object
        Throwable
    Error        Exception
Throwable继承自Object,Error和Exception继承自Throwable。Error比较特殊,它对应于我们常说的不可抗拒的外力,房屋中介的合同上总有一条,如遇不可抗拒的外力本合同中止,返还乙方押金。我不安地问:不可抗拒的外力指什么?中介回答:比如战争、彗星撞击地球等。对Java来说Error是指JVM内存耗尽等这类不是程序错误或者其他事情引起的特殊情况。一般地,程序不能从Error中恢复,因此你可以能眼睁睁地看着程序崩溃而不必责怪自己。严格来讲,Error不是异常,因为它不是继承自Exception。

10、谁之错?一般地,异常不是我们程序员的错,不是程序设计上的缺陷。比如读取一个重要文件,这个文件被用户误删了;正上着网呢,网线被用户的宠物咬断了。为了程序的健壮性,我们尽量考虑出现可能性大的异常,并处理,但我们不能穷尽。

11、异常的捕获之一。catch子句的参数是某种类型异常的对象,如果抛出的异常是该参数的子类,那么这个异常将被它捕获。也就是说被抛出的异常不会精确地寻找最匹配的捕获者(catch子句),只要是它的继承结构的直系上层就可以捕获它。

按照这个逻辑,catch(Exception e) 不就能捕获所有的异常吗?事实上,确实如此。但是一般地,不建议使用这种一站式的异常处理。因为这样就丢失了具体的异常信息,不能为某个具体的异常编写相应的异常处理代码,失去了异常处理的意义。从哲学角度来讲,具体问题要具体分析,能治百病的万能药一般都是无效的保健品。

Java在此处为什么这么设计呢?因为有另一种机制的存在,请看下条分解。

12、异常的捕获之二。当抛出一个异常时,Java试图寻找一个能捕获它的catch子句,如果没找到就会沿着栈向下传播。这个过程就是异常匹配。 Java规定:最具体的异常处理程序必须总是放在更普通异常处理程序的前面。这条规定再合理不过了,试想如果把catch(Exception e)放在最上面,那么下面的catch子句岂不是永远不能执行了?如果你非要把更普遍的异常处理放在前面,对不起,通不过编译!虽然编译器不会这样报错: “It is so stupid to do like that!”……

13、捕获或声明规则。如果在一个方法中抛出异常,你有两个选择:要么用catch子句捕获所有的异常,要么在方法中声明将要抛出的异常,否则编译器不会让你得逞的。
方案一:处理异常
    void ex(){
        try{
            throw new Exception();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
方案二:抛出去
    void ex() throws Exception{
        throw new Exception();
    }
比较一下行数就知道了,在代码的世界里推卸责任也是那么简单,一个throws关键字包含了多少人生哲理啊……现实生活中我们有很多角色,儿女、父母、学生、老师、老板、员工……每个人都占了几条。可是你能尽到所有责任吗?按照古代的孝道,父母尚在人世就不能远行。各种责任是有矛盾的,顾此失彼啊。

但是这条规则有个特例。一个继承自Exception名为RuntimeException的子类,也就是运行时异常,不受上述规则的限制。下面的代码完全能编译,只不过调用之后在运行时会抛出异常。
    void ex(){
        throw new RuntimeException();
    }

14、throw和thrwos关键字。throw用在方法体中抛出异常,后面是一个具体的异常对象。throws用在方法参数列表括号的后面,用来声明此方法会抛出的异常种类,后面跟着一个异常类。

15、非检查异常。RuntimeException、Error以及它们的子类都是非检查异常,不要求定义或处理非检查异常。Java2类库中有很多方法抛出检查异常,因此会常常编写异常处理程序来处理不是你编写的方法产生的异常。这种机制强制开发人员处理错误,使得Java程序更加健壮,安全。

16、自定义异常类型。觉得现有的异常无法描述你想抛出的异常,ok!Java允许你自定义异常类型,只需要继承Exception或者它的子类,然后换上有个性的名字。
    class NotEnoughMoney extends Exception {
        public NotEnoughMoney() {}
        public NotEnoughMoney(String msg) { super(msg); }
    }
希望大家在生活里不要抛出类似的异常。

17、重新抛出异常。一个很无聊的话题,纯粹的语法研究,实际意义不大。当catch子句捕获到异常之后可以重新抛出,那么它所在的方法必须声明该异常。
    void ex() throws Exception{
        try {
            throw new Exception();
        }
        catch (Exception mex) {
            throw me;
        }   
    }

18、异常处理机制的效率。待补充……

19、终止与恢复模型。异常处理理论上有两种模型:
一、终止模型。错误很关键且无法挽回,再执行下去也没意义,只能中止。“罗密欧,我们分手吧!”“好吧,朱丽叶!”
二、恢复模型。经过错误修正重新尝试调用原来出问题的方法。“罗密欧,我们分手吧!”“朱丽叶,我错了!请再原谅我一次吧!”“好的,再原谅你最后一次!”
显然我们更喜欢恢复模型,但在实际中,这种模式是不易实现和维护的。
例子:用户输入了非法的字符,分别按照两种模式处理
一、终止模型。输出出错信息而已,一旦用户手一抖眼一花你的代码就崩溃了
    double number;
    String sNumber = "";
    try {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        sNumber = bf.readLine();
        number = Double.parseDouble(sNumber);   
    } catch (IOException ioe) {
        System.err.println("some IOException");
    } catch (NumberFormatException nfe) {
        System.err.println(sNumber + " is Not a legal number!");
    }
    //System.out.println(number);

二、恢复模型。小样!不输入正确的数据类型就别想离开!
    double number = 0;
    String sNumber = "";
    while(true){
        try {
            BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
            sNumber = bf.readLine();
            number = Double.parseDouble(sNumber);
            break;    //如果代码能执行到这一行,就说明没有抛出异常
        } catch (IOException ioe) {
            System.err.println("some IOException");
        } catch (NumberFormatException nfe) {
            System.err.println(sNumber + " is Not a legal number!");
        }
    }
    System.out.println(number);

直到用户输入正确的信息才会被该代码放过。这是一种简单的恢复模型的实现,挺耐看的,我很喜欢!

20、try、catch、finally内变量的作用域和可见性。
在try块内定义的变量,它在catch或者finally块内都是无法访问到的,并且在整个异常处理语句之外也是不可见的。
补充一点初始化:第一个例中最后一句被注释掉了。number是在运行时由用户输入而初始化的,但是在编译时刻并没有初始化,编译器会抱怨的。

21、输出异常信息。捕捉到异常之后,通常我们会输出相关的信息,以便更加明确异常。
    catch (Exception mex) {
        System.err.println("caught a exception!");
    }
用标准错误流System.err比System.out要好。因为System.out也许会被重定向,System.err则不会。

22、更高级的话题我会补充上的,但是我的肚子抛出了Hungry异常,我必须catch然后调用eat()方法补充能量。昨晚的鱿鱼盖浇饭很好吃……
分享到:
评论

相关推荐

    Java语法总结.zip

    总之,"Java语法总结.zip"这个压缩包中的内容涵盖了Java编程语言的基础到高级语法,包括但不限于数据类型、控制结构、类与对象、继承与接口、异常处理、集合框架以及泛型和函数式编程等主题。学习并掌握这些知识,将...

    中信java培训资料------第一部分

    【归纳总结shi.doc】可能是对一段时间内学习内容的提炼,包含了关键知识点的梳理,比如类与对象的区别、封装、继承和多态性这面向对象的三大特性,以及异常处理机制和Java内存管理的基本原理,如垃圾回收机制。...

    2020最新Java企业面试题汇总-1000多份.txt

    根据给定文件的信息,我们可以总结出以下相关的Java知识点和面试准备要点: ### 一、Java基础知识 #### 1. Java语言特点 - **面向对象**:封装、继承、多态。 - **平台无关性**:通过JVM实现跨平台运行。 - **自动...

    java oop总结-编程程序

    ### Java OOP 总结与理解 #### 一、面向对象基本概念 在 Java 面向对象(Object-Oriented Programming, OOP)编程中,我们主要关注以下几个核心概念:类(Class)、对象(Object)、封装(Encapsulation)、继承...

    90.088.JAVA基础教程_Java基本语法-每天一考(90).rar

    总结来说,这个“90.088.JAVA基础教程_Java基本语法-每天一考(90)”的教程将带你走过Java编程的每一步,从理解基本语法元素到掌握面向对象的概念,再到实际编写和调试代码。每天的学习和练习将助你在Java编程的世界...

    Java面试突击-V3.0_Java面试文档_java面试_面试_

    2. **异常处理**:Java中的异常处理是程序健壮性的重要保障,学习如何使用try-catch-finally结构以及不同类型的异常类是必备知识。 3. **集合框架**:Java集合框架是存储和操作对象的关键工具,包括List、Set、Map...

    Java语法大全史上最全语法

    根据提供的文件信息,本文将对Java语法进行详细的解析与总结,包括基本的语法结构、关键字、数据类型、变量声明及转换等内容。 ### Java语言概述 Java是一种广泛使用的面向对象编程语言,由Sun Microsystems开发并...

    CoreJava串讲---超好!

    在Java编程领域,CoreJava是学习的基础,它涵盖了Java语言的核心概念和技术,包括语法、数据类型、控制结构、类与对象、集合框架等重要主题。这次的串讲内容将深入探讨这些基础知识,帮助开发者构建扎实的Java根基。...

    JAVA基础语法总结

    这篇总结将深入探讨Java的基础语法,帮助初学者理解并掌握Java编程的核心概念。 **1. Java程序结构** Java程序由类(Class)组成,每个类都包含方法(Method)。程序执行始于main方法。例如: ```java public class...

    java基础语法 汇总

    ### Java基础语法汇总 本文将基于给定的文件信息,对Java的基础语法进行一次全面而深入的解析。Java作为一种广泛使用的编程语言,在软件开发、Web应用、移动应用等多个领域都有着重要的地位。对于初学者而言,掌握...

    java基础教程-基本语法

    Java基础教程 - 基本语法 Java是一种广泛使用的高级编程语言,以其“一次编写,到处运行”的跨平台特性而闻名。本教程旨在帮助初学者掌握Java语言的基础语法,为后续深入学习打下坚实基础。 一、Java语言概述 Java...

    java-util-iterator.pdf java-util-iterator.pdf

    根据提供的文件信息,本文将深入探讨Java中的`java.util.Iterator`接口及其在集合类中的应用。我们将从以下几个方面进行详细解析: ### 一、集合类的根接口:Collection `Collection`接口是Java集合框架的基础,它...

    java程序员必读--基础篇

    总结起来,"java程序员必读--基础篇"覆盖了Java语言的基本概念、核心特性、语法结构、面向对象编程、异常处理、集合框架、多线程、I/O流和标准库的使用。通过深入学习和实践这些内容,Java程序员能够奠定坚实的技术...

    Java-Interview-Questions-总结各种面试题

    首先,让我们来看看Java的基础部分,这通常包括Java语法、数据类型、运算符、流程控制等。面试中,面试官可能会询问你关于面向对象编程的基本概念,如封装、继承和多态。此外,理解异常处理机制、垃圾回收机制(GC)...

    Java语法大全.pdf

    以上是对Java语法的概览,包括了关键字、数据类型、控制结构、类和方法定义等基本要素,以及如何编译Java源代码并由JVM来执行。通过学习这些基础知识,可以开始编写简单的Java程序,并逐步深入理解更高级的Java编程...

    java 实现词法分析器以及语法分析器

    总结来说,"java 实现词法分析器以及语法分析器"涉及了编程语言处理的核心技术,包括词法分析和语法分析。通过Java实现,我们可以更好地控制解析过程,并且加深对编译原理的理解。通过`WordThink3.java`和`...

    java 技术总结.--java 技术

    这篇“Java技术总结”将深入探讨Java的核心概念、语法特性、开发工具以及相关框架,旨在为学习者提供一个全面且深入的Java知识体系。 一、Java语言基础 Java是一种面向对象的编程语言,由Sun Microsystems(现已被...

    Java第6-7章作业

    Java 第6-7章作业的知识点总结 ...Java 第6-7章作业涵盖了Java 的基本语法、控制结构、方法、数组、面向对象编程和异常处理等知识点,这些知识点是Java 开发的基础,我们需要通过实践和编程练习来巩固这些知识点。

    CoreJava考试试题---达内科技.pdf

    根据给定的文件信息,我们可以总结出一系列关于Java编程语言的重要知识点,这些知识点不仅涵盖了基本的语法和概念,还深入到了面向对象编程的核心原理。以下是详细的解析: ### 1. 文档注释与Javadoc - **知识点:...

    java基础核心总结归纳---参考手册--心得手册-学习资料-总结经验

    3. Java 基本语法 - 数据类型:包括整数型(byte, short, int, long),浮点型(float, double),字符型(char)和布尔型(boolean)。 - 基础语法:如变量声明、方法定义、控制流(条件语句,循环语句,跳转语句...

Global site tag (gtag.js) - Google Analytics