Java中的异常 Exception

  java.lang.Exception类是Java中所有异常的直接或间接父类。即Exception类是所有异常的根类。

  比如程序: 

public class ExceptionTest
{public static void main(String[] args){int a = 3;int b = 0;int c = a / b;          System.out.println(c);}
}

  编译通过,执行时结果:

  Exception in thread "main" java.lang.ArithmeticException: / by zero

  at com.learnjava.exception.ExceptionTest.main(ExceptionTest.java:9)

  因为除数为0,所以引发了算数异常。

  比较常见的异常还有这种:空指针异常

  java.lang.NullPointerException是空指针异常,出现该异常的原因在于某个引用为null,但却调用了它的某个方法,这时就会出现该异常。

Java中的异常分为两大类:

  1.Checked Exception(非Runtime Exception

  2.Unchecked ExceptionRuntime Exception

运行时异常

  RuntimeException类是Exception类的子类,它叫做运行时异常,Java中的所有运行时异常都会直接或者间接地继承自RuntimeException类。

  Java中凡是继承自Exception,而不继承自RuntimeException类的异常都是非运行时异常

异常处理的一般结构

    try{// 可能发生异常的代码// 如果发生了异常,那么异常之后的代码都不会被执行
    }catch (Exception e){// 异常处理代码
    }finally{// 不管有没有发生异常,finally语句块都会被执行}

  比如本文最开始的除法运算代码,加入异常处理之后: 

public class ExceptionTest
{public static void main(String[] args){int c = 0;try{int a = 3;int b = 0;// 这块代码出现了异常c = a / b;// 那么异常之后的代码都不会被执行System.out.println("Hello World");}catch (ArithmeticException e){e.printStackTrace();}finally{//不管有没有发生异常,finally语句块都会被执行System.out.println("Welcome");}System.out.println(c);// 当b为0时,有异常,输出为c的初始值0}
}

多个catch

  一个try后面可以跟多个catch,但不管多少个,最多只会有一个catch块被执行。

异常处理方法

  对于非运行时异常(checked exception),必须要对其进行处理,否则无法通过编译。

  处理方式有两种:

  1.使用try..catch..finally进行捕获;

  2.在产生异常的方法声明后面写上throws 某一个Exception类型,如throws Exception,将异常抛出到外面一层去。

  对非运行时异常的处理详见代码例子:

  处理方式1:将异常捕获

将异常捕获

public class ExceptionTest2
{public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
    {System.out.println("Hello World");// 抛出异常throw new Exception();}public static void main(String[] args){ExceptionTest2 test = new ExceptionTest2();try{test.method();}catch (Exception e){e.printStackTrace();}finally{System.out.println("Welcome");}}}

  处理方式2:将异常继续向外抛出

将异常抛出

public class ExceptionTest2
{public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
    {System.out.println("Hello World");// 抛出异常throw new Exception();}public static void main(String[] args) throws Exception // main方法选择将异常继续抛出
    {ExceptionTest2 test = new ExceptionTest2();test.method(); // main方法需要对异常进行处理// 执行结果:// Hello World// Exception in thread "main" java.lang.Exception// at com.learnjava.exception.ExceptionTest2.method(ExceptionTest2.java:10)// at com.learnjava.exception.ExceptionTest2.main(ExceptionTest2.java:17)
    }}

  对于运行时异常(runtime exception),可以对其进行处理,也可以不处理。推荐不对运行时异常进行处理。

自定义异常

  所谓自定义异常,通常就是定义一个类,去继承Exception类或者它的子类。因为异常必须直接或者间接地继承自Exception类。

  通常情况下,会直接继承自Exception类,一般不会继承某个运行时的异常类。

  自定义异常可以用于处理用户登录错误,用户输入错误提示等。

  自定义异常的例子:

  自定义一个异常类型: 

public class MyException extends Exception
{public MyException(){super();}    public MyException(String message){super(message);}
}

  一种异常处理方式:

一种异常处理方式

public class ExceptionTest4
{public void method(String str) throws MyException{if(null == str){throw new MyException("传入的字符串参数不能为null!");}else{System.out.println(str);}}public static void main(String[] args) throws MyException //异常处理方式1,不断向外抛出
    {ExceptionTest4 test = new ExceptionTest4();test.method(null);}
}

  另一种异常处理方式:

异常处理方式二

public class ExceptionTest4
{public void method(String str) throws MyException{if (null == str){throw new MyException("传入的字符串参数不能为null!");}else{System.out.println(str);}}public static void main(String[] args){//异常处理方式2,采用try...catch语句try{ExceptionTest4 test = new ExceptionTest4();test.method(null);}catch (MyException e){e.printStackTrace();}    finally{System.out.println("程序处理完毕");}}
}

  前面说过,可以有多个catch块,去捕获不同的异常,真正执行的时候最多只进入一个catch块

  下面这个例子,定义了两种自定义的异常类型:

多种异常

public class MyException extends Exception
{public MyException(){super();}public MyException(String message){super(message);}
}public class MyException2 extends Exception
{public MyException2(){super();}public MyException2(String message){super(message);}}public class ExceptionTest4
{public void method(String str) throws MyException, MyException2{if (null == str){throw new MyException("传入的字符串参数不能为null!");}else if ("hello".equals(str)){throw new MyException2("传入的字符串不能为hello");}else{System.out.println(str);}}public static void main(String[] args){// 异常处理方式2,采用try...catch语句try{ExceptionTest4 test = new ExceptionTest4();test.method(null);}catch (MyException e){System.out.println("进入到MyException catch块");e.printStackTrace();}catch (MyException2 e){System.out.println("进入到MyException2 catch块");e.printStackTrace();}finally{System.out.println("程序处理完毕");}}
}

  我们可以使用多个catch块来捕获异常,这时需要将父类型的catch块放到子类型的catch块之后,这样才能保证后续的catch块可能被执行,否则子类型的catch块将永远无法到达,Java编译器会报错。

  如果异常类型是独立的,那么它们的前后顺序没有要求。

  如对上面的代码进行改动后,如下列出:

多个catch语句块的顺序

public class ExceptionTest4
{public void method(String str) throws Exception // 也可以声明Exception,只要声明的可以涵盖所有抛出的异常即可
    {if (null == str){throw new MyException("传入的字符串参数不能为null!");}else if ("hello".equals(str)){throw new MyException2("传入的字符串不能为hello");}else{System.out.println(str);}}public static void main(String[] args){// 异常处理方式2,采用try...catch语句try{ExceptionTest4 test = new ExceptionTest4();test.method(null);}catch (MyException e){System.out.println("进入到MyException catch块");e.printStackTrace();}catch (MyException2 e){System.out.println("进入到MyException2 catch块");e.printStackTrace();}catch (Exception e){//虽然需要加上,但是这块代码不会被执行,只是为了编译成功System.out.println("进入到MyException catch块");e.printStackTrace();//如果去掉前面两个catch块或其中之一,则发生该异常时就会进入此catch块//catch块的匹配是按照从上到下的顺序,所以这个块如果放在最前面就会捕获所有的异常,后面的块永远不会执行,这时候会提示编译错误
        }finally{System.out.println("程序处理完毕");}}
}

面试常考题型

  try块中的退出语句

  虽然实际开发中不会遇到这样的情况,但是笔试面试时有关异常经常会问到如下情况:

笔试面试题解析

public class ExceptionTest5
{public void method(){try{System.out.println("进入到try块");//return;//会先执行finally块再返回//虚拟机退出//System.exit(0);//不会执行finally块中的语句,直接退出
        }catch (Exception e){System.out.println("异常发生了!");}finally{System.out.println("进入到finally块");}System.out.println("后续代码");}public static void main(String[] args){ExceptionTest5 test = new ExceptionTest5();test.method();}
}

  在加上return语句前,程序输出:

    进入到try块

    进入到finally块

    后续代码

  如果在try块中加入return语句:

  程序执行输出:

    进入到try块

    进入到finally块

  说明try块中有return语句时,仍然会首先执行finally块中的语句,然后方法再返回。

  如果try块中存在System.exit(0);语句,那么就不会执行finally块中的代码,因为System.exit(0)会终止当前运行的Java虚拟机,程序会在虚拟机终止前结束执行。

参考资料

  圣思园张龙老师Java SE系列视频教程。

Java 异常基础 Exception相关推荐

  1. Java异常基础+原理解析+自定义异常

    Java异常基础+原理解析 1.什么是异常呀? 程序中的异常就好比人生病了,即再程序的运行过程中.出现非正常的情况,导致jvm非正常终止终止 异常的体系: 异常的的根类为java.lang.Throw ...

  2. java e.getmessage() null,浅谈Java异常的Exception e中的egetMessage()和toString()方法的区别...

    Exception e中e的getMessage()和toString()方法的区别: 示例代码1: public class TestInfo { private static String str ...

  3. java 抛出异常_我的Java Web之路51 - Java异常基础

    本系列文章旨在记录和总结自己在Java Web开发之路上的知识点.经验.问题和思考,希望能帮助更多(Java)码农和想成为(Java)码农的人. 目录 介绍 异常的本质 Java异常的设计 Java异 ...

  4. 1.1 Java异常(Exception)处理及常见异常

    计算机程序的编写也需要考虑处理这些异常情况.异常(exception)是在运行程序时产生的一种异常情况,已经成为了衡量一门语言是否成熟的标准之一.目前的主流编程语言,如 C++.c#.Ruby 和 P ...

  5. 【Java】基础知识整理

    写在前面 吹了这么久Python,怎么说也得照看照看老本行--Java吧,那就来吧. 比较起继续研究一些艰深的知识,我更愿意暂时的回顾一些自己在成长路上遗漏的或者遗忘的小知识,所以有了这个系列的博文. ...

  6. java异常网,Java异常实践事项

    在大学项目开发中, 你有没发现自己做的项目总是出现bug,不仅仅出现bug,而且很难根据异常信息找到异常源.我当时也是非常懊恼, 可怕的是不知道怎么维护... 软件Java异常需要理解基础的知识, 在 ...

  7. Java基础-异常(Exception)处理

    Java基础-异常(Exception)处理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.异常的概述 什么是异常?Java代码在运行时期发生的问题就是异常.在Java中,把异 ...

  8. Java 异常Exception

    Java异常处理总结 异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制异常痛苦,同一个异常 ...

  9. JAVA异常和基础类库

    #知识点总结第四篇   1.Java中导致程序中断运行的错误称为异常   2.Exception异常分为可查异常和不可查异常两种,且不可察异常一般为RuntimeException和它的子类异常,其他 ...

最新文章

  1. 基于OpenCV的人员剔除
  2. powerbi输入数据_Power BI 的多种共享方式
  3. 深入Ajax架构和最佳实践读书笔记
  4. java异常怎么输出到页面_怎么把抛出的异常信息输出到SWING 界面上
  5. 【MFC】MFC消息处理和映射
  6. 【学习笔记】Docker - 02. 在容器中运行软件(上)
  7. 100篇架构文章打包,及offer面试题下载
  8. C#.NET Split 的几种使用方法
  9. touch事件的分发和消费机制
  10. java 编辑pdf表格_Java 生成pdf表格文档
  11. glibc升级失败及处理过程
  12. DVB电视机顶盒工作原理
  13. 十大算法简单介绍以及例题
  14. NFS 服务器启动失败
  15. Named Entity Recognition for Chinese Social Media with Jointly Trained Embedding 笔记
  16. 7个免费的云平台,快来发布你的项目吧
  17. midaspay能删除吗_midaspay 什么意思
  18. OpenCV—Python 对比度与亮度调整
  19. 随机抽人名小程序_分析并实现一个简单的抽人程序
  20. 易语言利用Vs2017Linker编译器

热门文章

  1. 让 ScrollViewer 的滚动带上动画
  2. [转]阮一峰:蒙特卡罗方法入门
  3. Sqoop_ 简单介绍
  4. Java学习-----单例模式
  5. 【转】ubuntu UltraEdit 反复试用的办法
  6. vb破解万能断点816c24
  7. 经常下载的朋友注意了,教你怎样硬盘零伤害(从论坛上拷下来收藏的)
  8. C#中的OOP相关概念
  9. 2016年ADAS行业发展潜力及行业发展趋势分析【图】
  10. 对互联网用户分类的思考