Java基础(55):Exception类详解(转)
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 Exception(Runtime 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基础(55):Exception类详解(转)的更多相关文章
- Java基础-面向接口编程-JDBC详解
Java基础-面向接口编程-JDBC详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.JDBC概念和数据库驱动程序 JDBC(Java Data Base Connectiv ...
- java基础(3)--详解String
java基础(3)--详解String 其实与八大基本数据类型一样,String也是我们日常中使用非常频繁的对象,但知其然更要知其所以然,现在就去阅读源码深入了解一下String类对象,并解决一些我由 ...
- Java基础13:反射详解
本节主要介绍Java反射的原理,使用方法以及相关的技术细节,并且介绍了关于Class类,注解等内容. 具体代码在我的GitHub中可以找到 https://github.com/h2pl/MyTech ...
- java基础6 面向对象的详解
本文知识点(目录): 1.1.万物皆对象 1.2.面向对象的概述 1.3.面向对象(java语言)与面向过程(C语言)对比 1.4.面向过程 1.5.对象 1.6.面向对 ...
- java线程基础知识----SecurityManager类详解
在查看java Thread源码的时候发现一个类----securityManager,虽然很早就知道存在这样一个类但是都没有深究,今天查看了它的api和源码,发现这个类功能强大,可以做很多权限控制策 ...
- Java双刃剑之Unsafe类详解
前一段时间在研究juc源码的时候,发现在很多工具类中都调用了一个Unsafe类中的方法,出于好奇就想要研究一下这个类到底有什么作用,于是先查阅了一些资料,一查不要紧,很多资料中对Unsafe的态度都是 ...
- Java基础(44):ArrayList使用详解
1.什么是ArrayList ArrayList就是传说中的动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处: a.动态的增加和减少元素 b.实现了IColle ...
- 【Java基础】HashMap原理详解
哈希表(hash table) 也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,本文会对java集合框架中Has ...
- java基础之类与继承 详解
Java:类与继承 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封装.继承.多态这四大特性都离不开类,只有存在类,才能体现面向对象编程的特点,今天我们就来了解一些类与继承的相关知 ...
随机推荐
- NRF51822之发射功率
设置蓝牙的TX Power 使用的函数sd_ble_gap_tx_power_set(int8_t tx_power); 参看例子为 S110/ble_app_proximity #define ...
- yaf在windows7下32位的安装教程
首先下载php_yaf.dll文件http://pecl.php.net/package/yaf/2.2.9/windows 打开扩展extension=php_yaf.dll 然后下载工具 http ...
- 答CsdnBlogger问-关于定时和后台服务问题
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 前段时间写了不少博客,在问答页面也陆续回答几十个问题,之后Csdn乙同学找到我,说要推荐我参加问答类 ...
- JMX初体验
这些天在看<How Tomcat Works>这本书.里面讲到了JMX的内容.对我来说是个新知识点. JMX--Java Management Extensions,即Java管理扩展,是 ...
- 【Android开发学习笔记】【第一课】初识New Project,工程文件介绍
初学者新建一个Andriod工程后,往往不知道Pakage Explorer区域的每个文件是什么作用,今天学习了一下,自我总结一下. 1.先新建一个工程 2.输入名称,以及支持的SDK版本等(这些可以 ...
- ArcGIS API for Silverlight 调用GP服务准备---GP模型建立、发布、测试
原文:ArcGIS API for Silverlight 调用GP服务准备---GP模型建立.发布.测试 第一篇.GP降雨量等值线建模.发布及测试 在水利.气象等行业中,要在WebGIS中实现空间分 ...
- Spark Programming--Actions
first def first(): T first返回RDD中的第一个元素,不排序. 例子: count def count(): Long count返回RDD中的元素数量 例子: reduce ...
- [LeetCode]题解(python):036-Valid Sudoku
题目来源 https://leetcode.com/problems/valid-sudoku/ etermine if a Sudoku is valid, according to: Sudoku ...
- Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable con
AFHTTPSessionManager * manager = [AFHTTPSessionManager manager]; manager.responseSerializer.acceptab ...
- iOS8 推送注册方式改变的问题
不久之后iPhone 6/6 plus就会在国内如雨后春笋般遍地开花了.iOS 8早已现行一步,不过有的开发者也注意到了在iOS 8上推送通知的注册方式有所变化,报错提示为: 1 registerFo ...