/*总结:异常基础
* 一:有关java异常处理体系
* java异常体系的最高父类是throwable(是一个超类),他的直接子类有二个,分别是Error和Exception二个类;
* (1)其中Error是错误类,用来处理程序中出现的错误问题的(是比较严重的问题,一般是不能提前预测的)。
* (2)Exception是重点要学习的类,叫做异常处理类。是来处理程序异常的最高父类。
* (3)值得注意的是处理异常的主要方法都在throwable这个类中可以找到,其他的子类只是继承他的方而已。主要的方法有:
* 构造函数throwable(),throwable(String message) ,getMessage() ,printStackTrace(),toString()等等方法;
他的子类中主要是重写自己的构造函数就可以了。一定要注意的是在构造函数里,一般只需要使用super调用父类的构造函数来初始化数据就可以了。可以看看
*
* 二:java的异常处理机制:
* (1)默认异常处理:例题1
* class Exception
* {
* public static int show(int[] arr,int index)
* {
* return arr[index];//数组角标越界
* }
* public static void main(String[] args)
* {
* int a[]={1,2,3};
* show(a,3);
* }
* JVM的处理:当程序执行(运行)到 return arr[index]语句是;因为数组角标是越界的。此时自动生成 throw ArrayIndexOutOfBoundsException()
* 语句 而且直接throw到主函数里面去,主函数也无法处理这个问题,再抛给调用主函数的JVM,JVM将默认调用抛出对象假如叫E的printStackTrace()函数,
* 在控制台上输出异常信息。输出:java.lang.ArrayIndexOutOfBoundsException: 数据角标越界:3 注意throw后面的语句是不再执行的;
* (2)自定义异常处理机制:基础
* 1,就是自己定义异常处理类;注意的是一定要继承Exception或者是他的子类(一般是RuntimeException),这样就具有可抛性。就是可以被throw和
* throws抛出。
* 2,throws throw的关系
* throw是抛出异常处理对象的,是异常处理机制的关键步骤,并且使用方法体里面。
* throws是用来抛出类的,作用(important):放在方法的声明上,用来告诉调用该方法者这个方法可能存在的异常,这样有利于调用者调用时小心一点处理这个
* 问题。如果这个方法可能会出现多个异常的话,那就throws多个类就可以了(注意用,号隔开)。举个例子2
* package Demo;
class ArrayException extends Exception
{
public ArrayException()
{}
public ArrayException(String s)
{
super(s);
}
}
class Demo1
{
public static int show(int[] arr,int index) throws ArrayException //什么可能被抛出的异常类
{
if(index >=3)
{
throw new ArrayException("数据角标越界:"+index);//
}
return arr[index];
}
}
public class test1 {
public static void main(String[] args)
{
int a[]={1,2,3};
try
{
Demo1.show(a,3);
}
catch(ArrayException s)
{
System.out.println(s.toString());
}
catch(ArrayIndexOutOfBoundsException s)
{
System.out.println(s.toString());
}
System.out.println("over");
return ;
}
}
( 3)异常处理机制:重点(也是我刚开始最不理解的一部分)
* 下面来说说Exception的一个特殊子类RuntimeException这个类(very important)
* 异常的分类:
1,编译时被检测异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系。
这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式。
这样的问题都可以针对性的处理。比如你输入的数字格式不对,可以直接改过来就好;
2,编译时不检测异常(运行时异常):就是Exception中的RuntimeException和其子类。
这种问题的发生,无法让功能继续,运算无法进行,更多是因为调用者的原因导致的而或者引发了内部状态的改变导致的。
那么这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者对代码进行修正。
所以自定义异常时,要么继承Exception。要么继承RuntimeException。
总结:就是RuntimeException和其子类在偏译是不需要被检测的,运行时如果发现有异常错误就直接强制停掉。
假如例子2中的ArrayException是继承RuntimeException的话那么在show函数的声明上就不用throws该类了,
其实数组角标越界这种异常是不需要再偏译的时候检测的(即用throws声明),这应该是运行时处理的问题;下面是例子3
class FuShuIndexException extends Exception
{
FuShuIndexException()
{}
FuShuIndexException(String msg)
{
super(msg);
}
}
class Demo
{
public int method(int[] arr,int index)throws FuShuIndexException
{
if(arr==null)
throw new NullPointerException("数组的引用不能为空!");
if(index>=arr.length)
{
throw new ArrayIndexOutOfBoundsException("数组的角标越界啦,哥们,你是不是疯了?:"+index);
}
if(index<0)
{
throw new FuShuIndexException("角标变成负数啦!!");
}
return arr[index];
}
}
class ExceptionDemo3
{
public static void main(String[] args) throws FuShuIndexException//声明可能抛出自定义类;
{
int[] arr = new int[3];
Demo d = new Demo();
int num = d.method(null,-30);//这样是抛给JVM的意思;JVM调用printStackTrace()函数来处理;继承下来了嘛
System.out.println("num="+num);//当然你自己可以处理的话就自己处理;用try catch语句;
System.out.println("over");
}
}
(4)try catch机制:这个是比较简单的问题,不过很重要。例子2 注意的是:try catch语句后面的其他语句是可以被执行的;
(5)finally这也是异常处理的一个关键字,里面的代码是一定会被执行的(除了使用exit(0)退出JVM);
注意:finally通常用来释放和关闭资源的;看下面例4,
class Demo
{
public int show(int index)throws ArrayIndexOutOfBoundsException
{
if(index<0)
throw new ArrayIndexOutOfBoundsException("越界啦!!");
int[] arr = new int[3];
return arr[index];
}
}
class ExceptionDemo5
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int num = d.show(-1);
System.out.println("num="+num);
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println(e.toString());
// return ;
// System.exit(0);//退出jvm。
}
finally//通常用于关闭(释放)资源。
{
System.out.println("finally");
}
System.out.println("over");
}
}
/*
连接数据库
查询。Exception
关闭连接。
*/
/*
try catch finally 代码块组合特点:
1,
try catch finally
2,
try catch(多个)当没有必要资源需要释放时,可以不用定义finally。
3,
try finally 异常无法直接catch处理,但是资源需要关闭。
void show()throws Exception
{
try
{
//开启资源。
throw new Exception();
}
finally //如果不使用finally的话就会造成资源无法在短时间内关闭
{
//关闭资源。
}
/*
catch(Exception e)
{
}
}
(6)异常处理的一个运用:通过这个运用来总结前面的知识点;
/*
毕老师用电脑上课。
问题领域中涉及两个对象。
毕老师,电脑。
分析其中的问题。
比如电脑蓝屏啦。冒烟啦。
*/
/*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是正常状态,1是蓝屏状态,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 e;//抛出这个异常,收到信息的人(调用者)是处理不了的。throw下面那个就是“异常转换”这个是比较重要的;
throw new NoPlanException("课时进度无法完成,原因:"+e.getMessage());
}
}
public void test()
{
System.out.println("大家练习");
}
}
class ExceptionTest
{
public static void main(String[] args)
{
Teacher t = new Teacher("毕老师");
try
{
t.prelect();
}
catch (NoPlanException e)
{
System.out.println(e.toString()+"......");
System.out.println("换人");
}
}
}
/*
下面是例5:有关数据库的关闭(部分代码),异常转换机制的运用;
class NoAddException extends Exception//没有完成数据增加异常;
{
NoAddException()
{
super("数据库添加异常");
}
}
class SqlDemo
{
void addData(Data d)throws NoAddException
{
//连接数据库
try
{
添加数据。出现异常 SQLException();
}
catch(SQLException e)//这里实现了“异常转换”,这样调用数据库的人员才知道是发生了数据库添加失败的异常,不然的话调用者是不知道SQL异常的;
{
//处理代码。
throw new NoAddException();
}
fianlly //注意;
{
关闭数据库。
}
}
}
综述:
这二个结构是比较好的异常处理机制;不仅涉及到throw throws的使用,也涉及到try catch finally异常处理机制;还有就是使用了“异常转换机制”
其中 finally使用来关闭或者是释放资源的
三 : 异常处理的小细节问题处理:
异常的注意事项:记住,理解就可以了,不需要太注意;
1,子类在覆盖父类方法时,父类的方法如果抛出了异常,
那么子类的方法只能抛出父类的异常或者该异常的子类。例2,里面包括了原因;
2,如果父类抛出多个异常,那么子类只能抛出父类异常的子集。简单说:
子类覆盖父类只能抛出父类的异常或者子类或者子集。
注意:如果父类的方法没有抛出异常,那么子类覆盖时绝对不能抛,就只能try catch处理;看例1
例1
interface Inter
{
void function();
}
class D implements Inter
{
public void function()//throws Exception这样是不行的,偏仪器会报错的;
{}
}
例2:
/*Exception
|--A
|--B
|--C
class A extends Exception
{
}
class B extends A
{
}
class C extends Exception
{
}
class Fu
{
void show()throws A
{}
}
class Test
{
void method(Fu f)//Fu f = new Fu();Fu f=new Zi();//
{
try
{
f.show();
}
catch (A a)//抛出的不是A异常的或者其子类,那么这个机制就是错误的;这就是原因;
{
}
}
}
class Zi extends Fu
{
void show()throws C//假如是throw异常类C
{
}
}
class DemoTest
{
public static void main(String[] args)
{
Test t = new Test();
t.show(new Fu());//可以使用的
t.show(new Zi());//假如后面Fu有了子类,那么。。看上面。。
}
}
*/
异常处理总结(我自己的理解)
最新推荐文章于 2022-09-24 11:45:24 发布