------- android培训、java培训、期待与您交流! ----------
黑马学习日志之八 异常
1 异常
1.1 异常描述
程序在运行中出现不正常情况。
当编译时DOS中出现异常语句代表此程序已经没有语法错误,解决异常即可运行。
异常由来:
问题也是现实生活中的事物,也可以通过Java类进行描述,并封装成对象。其实就是Java对不正常情况进行描述后的对象体现。
问题成分:
严重的问题:error类 一般不编写针对性代码进行处理。
不严重的问题:Exception类 可以使用针对性的处理进行处理。如:运行时异常 数组 下标越界 空指针异常 类型转换异常
1.2 异常处理
Java提供了特有语句进行处理。
try
{
需要被检测的代码;
}
catch (异常类 变量)
{
异常处理的代码;(处理方式)
}
finaly
{
一定会执行的语句;
}
处理过程:
try中检测到异常会将异常对象传递给catch,catch捕获到异常进行处理。
finally里通常用来关闭资源。比如:数据库资源,IO资源等。
注意:try是一个独立的代码块,在其中定义的变量只在该变量块中有效。
如果在try以外继续使用,需要在try建立引用。
1.3 对捕获的异常对象进行常见方法操作
e.getMessage() //异常信息 返回String
e.toString() //异常名称 异常信息 返回String
e.printStackTrace() //默认打印 异常名称 异常信息 异常出现的位置
JVM默认的异常处理机制,就是调用printStackTrace方法打印异常堆栈的跟踪信息。
在函数上声明异常: throws Exception
1.4 对多异常的处理
(1)声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
(2)声明几个异常,就对应有几个catch块。
如果多个catch块中的异常出现继承关系。父类异常catch块放在最下面。建议在进行catch处理时,catch中一定要定义具体处理方式。
1.5 自定义异常
因为项目中会出现特有的问题,将特有问题进行自定义的异常封装。手动通过throw抛出一个异常
当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作,要么在内部try catch处理,要么在函数上声明让调用者处理。
自定义异常注意:必须是自定义类继承Exception。因为父类Exception已经把异常信息操作完成了,子类在构造时,将异常信息通过super语句传递给父类,通过getMessage()获取异常信息。
继承Exception的原因:异常有一个特点:因为异常类和异常对象都被抛出,他们都具备可抛性,这个可抛性是Throwable这个体系独有特点。只有这个体系的类和对象才能被throw和throws操作。
throws和throw的区别:
throws使用在函数上,throw使用在函数内
throws后面跟异常类,可以跟多个,用逗号隔开。位于类的小括号和大括号之间
throw后跟的是异常对象。
例子:
class FuShuException extends Exception //getMessage();
{
private int value;
FuShuException()
{
super();
}
FuShuException(String msg,int value)
{
super(msg);
this.value = value;
}
public int getValue()
{
return value;
}
}
class Demo
{
int div(int a,int b)throws FuShuException
{
if(b<0)
throw new FuShuException("出现了除数是负数的情况------ / by fushu",b);//手动通过throw关键字抛出自定义异常对象。
return a/b;
}
}
class ExceptionDemo3
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.div(4,-9);
System.out.println("x="+x);
}
catch (FuShuException e)
{
System.out.println(e.toString());
//System.out.println("除数出现负数了");
System.out.println("错误的负数是:"+e.getValue());
}
System.out.println("over");
}
}
1.6 RuntimeException 运行时异常
Exception中有一个特殊子类异常,RuntimeException。
如果在函数中抛出该异常,函数上可以不用声明,编译一样通过;
如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。
注意:之所以不用在函数上声明,是因为不需要让调用者处理
当该异常发生,希望程序停止,因为在运行时,出现了无法继续运算的情况,希 望停止程序后由程序员对代码进行修正。
自定义异常时,如果该异常的发生无法再继续运算,就让自定义异常继承 RuntimeException。
1.7 异常分两种
(1)编译时被检测的异常(要声明处理 然后要么抛出要么捕获 。这个异常 通常函数内抛出异常对象 函数上要声明 实际运行中调用该函数 发生异常的话 要么ry catch处理 要么抛出
(2)编译时不被检测的异常(运行时异常,RuntimeException) 这个异常 通常函数内抛出异常对象 函数上不需要要声明 编译通过
例子: 毕老师讲课
class LanPingException extends Exception
{
LanPingException(String message)
{
super(message);
}
}
class MaoYanException extends Exception
{
MaoYanException(String message)
{
super(message);
}
}
class NoPlanException extends Exception
{
NoPlanException(String msg)
{
super(msg);
}
}
class Computer
{
private int state = 3;
public void run()throws LanPingException,MaoYanException
{
if(state==2)
throw new LanPingException("蓝屏了");
if(state==3)
throw new MaoYanException("冒烟了");
System.out.println("电脑运行");
}
public void reset()
{
state = 1;
System.out.println("电脑重启");
}
}
class Teacher
{
private String name;
private Computer cmpt;
Teacher(String name)
{
this.name = name;
cmpt = new Computer();
}
public void prelect()throws NoPlanException
{
try
{
cmpt.run();
}
catch (LanPingException e)
{
cmpt.reset();
}
catch (MaoYanException e)
{
test();
throw new NoPlanException("课时无法继续"+e.getMessage());
}
System.out.println("讲课");
}
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("换老师或者放假");
}
}
}
1.8 finally关键字
通常用于关闭资源,如关闭数据库连接。
finally
{
Finally中存放的一定会被执行的代码
}
异常处理三种格式
try catch finally一起用 try finally一起用 try catch一起用
注意:
Catch是处理异常的,如果没有catch就代表没有被处理过,如果该异常是检测时异常,那么必须声明。
1.9 异常在子类覆盖中的体现
(1)子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类异常或者其子类,或者不抛。 如果子类中确实产生了与父类不同的异常,那么子类内部必须try catch来处理。
(2)如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
(3)如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。 如果子类的方法发生了异常,就必须进行try catch处理,绝对不能抛。