当异常发生时,原本要接着执行的代码不再执行,转而让其他部分的代码来处理。如果没有代码负责处理,控制台会报告异常。

  异常出现时的执行机制

  异常机制最大的好处是:清晰地分开了 正常的业务逻辑遇到情况时的处理 代码。(当在业务逻辑中,有多步可能会抛出不同的异常时,异常处理机制的好处更得以体现。如果没有这种机制,也许会通过很多的if...else...来实现异常处理,甚至是多层嵌套的if...else...,这样的代码可读性很差)

  通过例子来理解:

package exception;

public class ExceptionCatch {
public static void main(String[] args) {
     try {
       //我们通过抛出异常来抽象真实的业务逻辑,可能某一步会出现异常,这时下面的代码就不再执行,转而到处理代码。
       //执行完处理代码之后不会再回到之前try里没执行完的代码继续执行,而是去往下执行try{}catch{}之后的代码。
throw new NullPointerException();
            throw new ArrayIndexOutOfBoundsException();
       throw ...                  
}catch(NullPointerException e) {
    //异常处理代码
}catch(ArrayIndexOutOfBoundsException e) {
       //异常处理代码
     }catch(Exception e){
       //异常处理代码
 }
}
}

  -----------------------------------------------------

  捕捉到异常之后怎么处理?

  当catch到异常之后,根据你的业务逻辑来对它进行处理,比如说可以弹出一个窗口来警告用户发生了错误,或者让程序自己重新执行或者终止掉等等。当然,如果现在处理不了这个异常,也可以将它再次抛出。

  处理完异常之后是回不到异常发生的地方继续执行以下的代码了,而是从catch{}后面的代码开始执行。

  一个异常只能被捕捉一次,捕捉之后这个异常就没有了。不可能再次捕捉到。

  -----------------------------------------------------

  自定义异常类的构造器getMessage()方法的使用 :

 package exception;

 //注意观察两个异常类构造器的区别。

  /**
  * 推断:
  * 第一个异常类是自己定义了一个String变量,在构造的时候是将信息传给了这个变量;
  * 而第二个异常类的构造器是覆盖了父类的构造方法,所以我们猜测,父类Exception里一定有一个String类型的成员变量(这个成员变量同样继承给了MyException子类),
  * 所以在构造的时候利用super()将父类的构造方法取过来,进而将信息传给了父类里的那个String成员变量。
  * 而getMessage()方法也是从父类那里继承来的,进而我们推断:getMessage()方法返回的正是那个String变量。
 * 在第一个异常类的那个从父类继承的String变量并没有被赋值,所以通过getMessage()取到的是null。
  */
 class MyException extends Exception {
String msg;
public MyException(String msg) {
this.msg = msg;
}
public void printMsg() {
System.out.println("msg = " + msg);
}
} class MyException2 extends Exception {
public MyException2(String s) {
super(s);
}
} public class E04_ExceptionClass {
public static void main(String args[]) {
try {
throw new MyException("MyException message");
} catch(MyException e) {
e.printMsg();
System.out.println("e.getMessage() = " + e.getMessage()); //输出为null。
} try {
throw new MyException2("MyException2 message");
} catch(MyException2 e) {
System.out.println("e.getMessage() = " + e.getMessage());
}
}
}
/*Output:msg = MyException message
* e.getMessage() = null
* e.getMessage() = MyException2 message
*/

  -----------------------------------------------------

  printStackTrace()方法:堆栈跟踪

  我们知道在程序代码执行的过程中,某个主线程可能会调用其他的代码程序,调用执行之后,回来继续执行主线程。这个过程中就需要堆栈来存储调用时的断点。(因为在嵌套调用的时候会需要存储多个断点,返回的时候再倒序依次返回,这要遵循后进先出的原则。)

  堆栈跟踪便可以看成是对代码调用的跟踪,当异常发生时可以根据该异常的printStackTrace()方法,打印出该异常的整个传递过程

  -----------------------------------------------------

  一个方法里如果会抛出异常,则必须在方法头部声明 throws 异常名 。如果不声明则必须在这个方法里通过 try{}catch{} 将异常处理掉。

  运行时刻的异常,如ArrayIndexOutOfBoundsException,NullPointerException等,不需要在方法头部声明。(Java核心技术里称这些未unchecked Exception,未检查异常。)

  一个方法可以声明多个异常抛出 throws 异常1 , 异常2 ,但是在以后调用该方法时必须有多个catch来捕捉不同的异常。温馨提示:往往在编程时,会把所有可能会有的异常(现在会有的和以后可能会有的)全都声明在方法之后,这是一种习惯。因为在后期在对该方法进行功能扩展时可能会遇到出现这些异常,而当时在声明这些异常之后编译器会提示你将这些异常一一catch,所以这时你只需要填补catch里的处理内容,这会来带一定的便利。

  下面是一个示例:

package exception;

class OpenException extends Throwable {}
class CloseException extends Throwable {} public class c {
public static int open() {
return -1;
} public static void readFile() throws OpenException,CloseException {
if(open() == -1) throw new OpenException();
} public static void main(String[] args) {
try {
readFile();
} catch (OpenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CloseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

  -----------------------------------------------------

  异常捕捉时的匹配

  • 子类异常可以被捕捉父类异常的catch捕捉
  • 如果有多个匹配的异常,会按书写的顺序来,顺序里的第一个匹配的catch来捕捉。

  -----------------------------------------------------

  继承关系下异常的声明

  • 覆盖一个方法时,子类方法声明的异常版本不能比父类方法所声明的多。
  • 子类的构造函数中,必须声明父类声明可能抛出的全部异常。

Java基础学习 -- 异常的更多相关文章

  1. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

  2. Java基础学习(3)

    Java基础学习(三) Java异常 Throwable类:所有异常的祖先类 Error:虚拟机异常.内存错误.没法处理 Exception:编码.环境.用户操作输入出现问题 非检查异常(自动捕获): ...

  3. Java基础学习-- 继承 的简单总结

    代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...

  4. Java基础学习中一些词语和语句的使用

    在Java基础学习中,我们刚接触Java会遇到一些词和语句的使用不清的情况,不能很清楚的理解它的运行效果会是怎么样的,如:break,continue在程序中运行效果及跳转位置, 1.先来看看brea ...

  5. Java基础学习笔记总结

    Java基础学习笔记一 Java介绍 Java基础学习笔记二 Java基础语法之变量.数据类型 Java基础学习笔记三 Java基础语法之流程控制语句.循环 Java基础学习笔记四 Java基础语法之 ...

  6. 转载-java基础学习汇总

    共2页: 1 2 下一页  Java制作证书的工具keytool用法总结 孤傲苍狼 2014-06-24 11:03 阅读:25751 评论:3     Java基础学习总结——Java对象的序列化和 ...

  7. java基础学习总结——开篇

    java是我学习的第一门编程语言,当初学习java基础的时候下了不少功夫,趁着这段时间找工作之际,好好整理一下以前学习java基础时记录的笔记,当作是对java基础学习的一个总结吧,将每一个java的 ...

  8. Java基础学习笔记(一)

    Java基础学习笔记(一) Hello World 基础代码学习 代码编写基础结构 class :类,一个类即一个java代码,形成一个class文件,写于每个代码的前端(注意无大写字母) XxxYy ...

  9. java基础学习总结——java环境变量配置(转)

    只为成功找方法,不为失败找借口! 永不放弃,一切皆有可能!!! java基础学习总结——java环境变量配置 前言 学习java的第一步就要搭建java的学习环境,首先是要安装 JDK,JDK安装好之 ...

随机推荐

  1. python3.5 正则表达式

    我们平时上网的时候,经常需要在一些网站上注册帐号,而注册帐号的时候对帐号名称会有一些要求. 比如: 上面的图片中,输入的邮件地址.密码.手机号 才可以注册成功. 我们需要匹配用户输入的内容,判断用户输 ...

  2. ICSharpCode.SharpZipLib.dll 移植WP

    由于众所周知的原因. ICSharpCode.SharpZipLib.dll在Unity移植WP的时候出现诸多API不兼容,解决方案是在在Github上面找ICSharpCode.SharpZipLi ...

  3. ASP.NET MVC5 网站开发实践(二) Member区域 - 文章管理架构

    上次把member的用户部分完成,现在开始做文章管理部分.文章部分根据涉及显示现实文章列表,发布文章,修改文章,删除文章等功能.最终的实现目标是使用权限来控制用户是否能进行相应操作,管理员权限的会显示 ...

  4. MVC4做网站六后台管理:6.1.4管理员列表、添加及删除

    一.管理员列表 1.首先[AdministratorController]中添加返回分部视图的public PartialViewResult Index() /// <summary> ...

  5. invalidate()和postInvalidate() 的区别及使用

    Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中 ...

  6. android应用安全——(数据抓包)跟踪监控android数据包

    转载博客:http://blog.csdn.net/xyz_lmn/article/details/8808169 web开发中Chrome.IE.firefox等浏览器都自带提供了插件帮助开发者跟踪 ...

  7. 分享一个LiteDB做的简单考试系统辅助工具

    凌晨,被安排在公司值班,因为台风“灿鸿”即将登陆,风力太大,办公楼,车间等重要部分需要关注.所以无聊,那就分享一下,今天给朋友临时做的一个小的考试系统辅助工具吧.其实非常小,需求也很简单,但是可以根据 ...

  8. 【原创】开源Math.NET基础数学类库使用(08)C#进行数值积分

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

  9. scikit-learn 逻辑回归类库使用小结

    之前在逻辑回归原理小结这篇文章中,对逻辑回归的原理做了小结.这里接着对scikit-learn中逻辑回归类库的我的使用经验做一个总结.重点讲述调参中要注意的事项. 1. 概述 在scikit-lear ...

  10. 在Linux(ubuntu server)上面安装NodeJS的正确姿势

    上一篇文章,我介绍了 在Windows中安装NodeJS的正确姿势,这一篇,我们继续来看一下在Linux上面安装和配置NodeJS. 为了保持一致,这里也列举三个方法 第一个方法:通过官网下载安装 h ...