------
Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
异常的概述:
package cn.fuxi.exception;
/**
* 异常的体系
* 异常:是在运行时期发生的不正常情况.
* 在java中用类的形式对不正常情况经行了描述和封装对象.描述不正常的情况的类,就称为异常类.
* 1.以前是正常流程代码和问题处理代码相结合,现在将正常流程代码和问题处理代码分离,提高阅读性.
* 2.其实异常就是java通过面向对象的思想将问题封装成了对象,用异常类对其进行描述.
* 3.不同的问题用不同的类进行具体的描述.比如角标越界...空指针异常等等.
* 4.问题很多,意味着描述的类很多,将其共性经行向上抽取,形成了异常体系.
*
* 不正常情况分成了两大类:
* Throwable:无论是error,还是异常问题,发生就可以抛出,让调用者知道并处理.
* 该体系的特点就再在于Throwable及其所有的子类都具有可抛性.
*
* 可抛性到底指的是什么?怎么体现?
* 其实是通过两个关键字来体现的:throws throw
* 凡是可以被这两个关键字所操作的类和对象都具备可抛性.
*
* 1.一般不可处理的:Error
* 特点:是由jvm抛出符严重性问题.
* 这种问题发生,一般不针对性处理,直接修改程序.
* 2.可以处理的:Exception
* 该体系的特点:
* 子类的后缀名都是用其父类名作为后缀,阅读性很强.
*
* Throwable中的方法:
* 1.getMessage():获取异常信息,返回字符串.
* 2.toString():获取异常类名和异常信息,返回字符串.
* 3.printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void.
* 4.printStackTrace(PrintStream s):通常用该方法将异常内容保存在日志文件中,以便查询.
*/
class Demo{
public static int method(int[] arr,int index){
if(arr==null){
throw new NullPointerException("数组的引用不能为空!");
}
if(index >=arr.length){
throw new ArrayIndexOutOfBoundsException("数组角标越界:"+index);
}
return arr[index];
}
}
public class ExceptionDemo {
public static void main(String[] args) {
int[] arr = new int[3];
Demo.method(arr, 30);
}
}
运行结果:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 数组角标越界:30
at cn.fuxi.exception.Demo.method(ExceptionDemo.java:38)
at cn.fuxi.exception.ExceptionDemo.main(ExceptionDemo.java:47)
at cn.fuxi.exception.Demo.method(ExceptionDemo.java:38)
at cn.fuxi.exception.ExceptionDemo.main(ExceptionDemo.java:47)
自定义异常:
package cn.fuxi.exception;
/**
* 自定义异常
* 可以自定义出的异常为自定义异常.
* 对于角标为负数的情况,可以用负数角标异常来表示,负数角标这种异常在java中并没有定义过.
* 那就按照java异常的创建思想,面向对象,将负数角标经行自定义描述,并封装成对象.
* 这种自定义的问题描述称为自定义异常.
*
* P.S.如果让一个类称为异常类,必须要继承异常体系,因为只有称为异常体系的子类才有资格具备可抛性,
* 才可以被两个关键字所操作:throws throw.
*
* 自定义类继承Exception或者其子类,通过构造函数定义异常信息
*/
class DemoException extends Exception{
DemoException(String message){
super(message);
}
}
/*
*通过throw将自定义异常抛出.
*throws和throw的区别
*1.throws用于标识函数暴露出来的异常类,并且可以抛出多个,用逗号分隔.throw用于抛出异常对象.
*2.throws用在函数上,后面跟异常类名.throws用在函数内,后面跟异常对象.
*
* 定义功能方法时,需要把出现的问题暴露出来让调用者去处理,那么久通过throws在函数上标识.
*/
class FuShuIndexException extends Exception{
FuShuIndexException(){}
FuShuIndexException(String msg){
super(msg);
}
}
class Demo2{
public static int method(int[] arr,int index) throws FuShuIndexException {
if(index<0){
throw new FuShuIndexException("数组的角标是负数");
}
return arr[index];
}
}
public class ExceptionDemo2 {
public static void main(String[] args) throws FuShuIndexException {
int[] arr = new int[5];
Demo2.method(arr, -6);
}
}运行结果:
Exception in thread "main" cn.fuxi.exception.FuShuIndexException: 数组的角标是负数
at cn.fuxi.exception.Demo2.method(ExceptionDemo2.java:37)
at cn.fuxi.exception.ExceptionDemo2.main(ExceptionDemo2.java:46)
at cn.fuxi.exception.Demo2.method(ExceptionDemo2.java:37)
at cn.fuxi.exception.ExceptionDemo2.main(ExceptionDemo2.java:46)
异常的分类:
package cn.fuxi.exception;
/**
* 异常的分类:
* 1.编译时被检测异常:只要是Exception和其子类都是,初二了特殊子类RuntimeExc体系.
* 这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式.
* 这样的问题都可以针对性的处理.
*
* 2.编译时不检测异常(运行时异常):就是Exception中的RuntimeException和其子类.
* 这种问题的发生,无法让功能继续,运算无法运行,更多是因为调用的原因导致的或者引发了内
* 部状态的改变导致的.
* 那么这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者
* 对对代码经行调整.
* 所以自定义异常时,要么继承Exception,要么继承RuntimeException.
*/
class FuShuIndexException2 extends RuntimeException{
FuShuIndexException2(){}
FuShuIndexException2(String msg){
super(msg);
}
}
class Demo3{
public static int method(int[] arr,int index){//RuntimeException 不需要用throws抛出
if(index < 0){
throw new FuShuIndexException2("数组的角标是负数啦!");
}
return arr[index];
}
}
public class ExceptionDemo3 {
public static void main(String[] args) {
int[] arr = new int[5];
Demo3.method(arr, -9);
}
}
/*
*P.S.RuntimeException是那些可能在java虚拟机正常运行期抛出的异常的超类.
*可能在执行方法期间抛出当未被捕获的RuntimeException的任何子类都无需再throws子句中进行声明.
*/
运行结果:
Exception in thread "main" cn.fuxi.exception.FuShuIndexException2: 数组的角标是负数啦!
at cn.fuxi.exception.Demo3.method(ExceptionDemo3.java:24)
at cn.fuxi.exception.ExceptionDemo3.main(ExceptionDemo3.java:33)
at cn.fuxi.exception.Demo3.method(ExceptionDemo3.java:24)
at cn.fuxi.exception.ExceptionDemo3.main(ExceptionDemo3.java:33)
异常的捕捉:
package cn.fuxi.exception;
/**
* 异常处理的捕捉形式:
* 可以对异常经行针对性处理的方式.
*
* 具体的格式是:
* try{
* //需要被检查异常的代码
* } catch(异常类名 变量)//{该变量用于接收发生的异常对象
* //处理异常的代码.
* } finally{
* //一定会执行的代码.
* }
*
* P.S.finally代码块只有一种情况不会被执行,就是在之前执行了System.exit(0)//退出虚拟机
*
* 处理过程:
* try中检测到异常会将异常对象传递给catch,catch捕获到异常经行处理.
* finally里通常用来关闭资源.比如:数据库资源,IO资源等.
* 需要注意:try是一个独立的代码块,其中定义的变量只有在该变量块中有效.
* 如果try以外继续使用,需要在try外建立引用,在try中对其经行初始化.IO,Socket就会遇到.
*/
class FuShuIndexException4 extends RuntimeException{
FuShuIndexException4(){}
FuShuIndexException4(String msg){
super(msg);
}
}
class Demo4{
public static int method(int[] arr,int index){
if(arr == null){
throw new NullPointerException("没有任何数组实体");
}
if(index < 0){
throw new FuShuIndexException4("数组的角标是负数咯~~");
}
return arr[index];
}
}
public class ExceptionDemo4 {
public static void main(String[] args) {
int[] arr = new int[6];
try{
int num = Demo4.method(arr, -30);
System.out.println("num: "+ num);
}catch(NullPointerException e){
System.out.println(e);
}catch(FuShuIndexException4 e){
System.out.println("message: "+ e.getMessage());
System.out.println("String: "+ e);
e.printStackTrace();//jvm 默认的异常处理机制就是调用异常对象的这个方法
System.out.println("负数角标异常!!!!");
}catch(Exception e){//Exception的catch放在最后,是为了先处理有针对性的异常
System.out.println("e");
}
System.out.println("over");
}
}
运行结果:
message: 数组的角标是负数咯~~
String: cn.fuxi.exception.FuShuIndexException4: 数组的角标是负数咯~~
cn.fuxi.exception.FuShuIndexException4: 数组的角标是负数咯~~
at cn.fuxi.exception.Demo4.method(ExceptionDemo4.java:35)
at cn.fuxi.exception.ExceptionDemo4.main(ExceptionDemo4.java:44)
负数角标异常!!!!
over
异常处理方式:
String: cn.fuxi.exception.FuShuIndexException4: 数组的角标是负数咯~~
cn.fuxi.exception.FuShuIndexException4: 数组的角标是负数咯~~
at cn.fuxi.exception.Demo4.method(ExceptionDemo4.java:35)
at cn.fuxi.exception.ExceptionDemo4.main(ExceptionDemo4.java:44)
负数角标异常!!!!
over
异常处理方式:
package cn.fuxi.exception;
/**
* 异常处理的原则:
* 1.函数内容如果抛出需要检测的异常,那么函数上必须要声明.
* 否则,必须在函数内用try/catch捕捉,否则编译失败
*
* 2.如果调用到了声明异常的函数,要么try/catch,要么throws,否则编译失败.
*
* 3.什么时候catch,什么时候throws呢?
* 功能内容可以解决,用catch.
* 解决不了,用throws告诉调用者,由调用者解决.
*
* 4.一个功能如果抛出了多个异常,那么调用时,必须有对应多个catch进行针对性处理.
* 内部有几个需要检测的异常,就抛几个异常,抛出几个,就catch几个.
*
* try catch finally 代码块组合特点
* 1.try catch finally
* 2.try catch(多个):当没有资源需要释放时,可以不用定义finally.
* 3.try finally:异常无法直接catch处理,但是资源必须关闭.
*/
class Demo5{
public int show(int index){
if(index <0){
throw new ArrayIndexOutOfBoundsException("越界啦!!");
}
int[] arr = new int[3];
return arr[index];
}
}
public class ExceptionDemo5 {
public static void main(String[] args) {
Demo5 d5 = new Demo5();
try{
int num =d5.show(-4);
System.out.println("num = "+ num);
} catch(ArrayIndexOutOfBoundsException e){
System.out.println(e.toString());
System.out.println(e.getMessage());
System.out.println(e.getStackTrace());
System.exit(0);
}finally{//通常用于关闭(释放)资源
System.out.println("finally");//由于前面执行了System.exit(0);故不会执行finally
}
System.out.println("over");
}
}
运行结果:
java.lang.ArrayIndexOutOfBoundsException: 越界啦!!
越界啦!!
[Ljava.lang.StackTraceElement;@4e823618
越界啦!!
[Ljava.lang.StackTraceElement;@4e823618
案列:
package cn.fuxi.exception;
/**
* 老师用电脑上课.
*
* 问题领域中涉及两个对象.
* 毕老师,电脑
*
* 分析其中的问题
* 比如:电脑蓝屏,冒烟等.
*
* 异常注意事项:
* 1.RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明.
* 2.子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常,或者该异常的子类
* 3.如果父类抛出多个异常,那么子类只能抛出父类异常的子集.
* 简单说:子类覆盖父类只能抛出父类的异常,或者子类的子集.
*/
class LanPingException extends Exception{
LanPingException(String msg){
super(msg);
}
}
class MaoYanException extends Exception{
MaoYanException(String msg){
super(msg);
}
}
class NoPlanException extends Exception{
NoPlanException(String msg){
super(msg);
}
}
class Computer{
private int state = 1;//0,2
public void run() throws LanPingException, MaoYanException{
if(state == 1){
throw new LanPingException("电脑蓝屏啦!");
}
if(state == 2){
throw new MaoYanException("电脑冒烟啦!");
}
System.out.println("电脑正常运行");
}
public void reset(){
state =0;
System.out.println("电脑重启");
}
}
class Teacher{
private String name;
private Computer comp;
Teacher(String name){
this.name = name;
comp = new Computer();
}
public void prelect() throws NoPlanException{
try{
comp.run();
System.out.println(name + "讲课");
}catch(LanPingException e){
System.out.println(e.toString());
comp.reset();
prelect();
}catch(MaoYanException e){
System.out.println(e.toString());
test();//对电脑经行维修
throw new NoPlanException("课程进度无法完成,原因是:"+e.getMessage());
}
}
public void test(){
System.out.println("大家自习");
}
}
public class ExceptionDemo6 {
public static void main(String[] args) {
Teacher t = new Teacher("有熊老师");
try {
t.prelect();
} catch (NoPlanException e) {
System.out.println(e.toString()+"...");
System.out.println("换烈山老师");
}
}
}
运行结果:
cn.fuxi.exception.LanPingException: 电脑蓝屏啦!
电脑重启
电脑正常运行
有熊老师讲课
电脑重启
电脑正常运行
有熊老师讲课
本文深入讲解Java异常处理机制,包括异常体系、自定义异常、异常分类及处理方式等内容,并通过案例展示异常处理的具体应用。
1万+

被折叠的 条评论
为什么被折叠?



