异常
当方法中的代码出现错误异常的时候会被封装成一个异常对象抛给java虚拟机。java虚拟机会从包含异常方法的代码以及调用该方法的代码块中逐个寻找合适的处理异常的代码,如果有合适的代码可以处理这个异常,那么java虚拟机会将这个异常对象交给它来处理。如果虚拟机寻遍了所有的代码,没有找到合适的方法,虚拟机会自行终止,程序停止运行。
try:一般会将可能引起异常的代码写入try代码块中,try代码块中的代码可以是一行或者多行。你可以将每行异常代码写入一个try代码块中,然后分别用catch代码块对其捕获处理。也可以将整个可能引起异常的代码写入try代码块中并对其进行捕获。
catch:try代码块之后直接跟着一个或者多个catch代码块,对异常进行捕获和处理。catch代码块中的参数必须声明异常的类型,并且最好使用从throwable类中继承的异常类型名称,以便catch更好的对异常进行捕获和处理。在try代码块和catch代码块之间不允许有任何代码。你可以在catch代码块中打印这个异常的信息,也可以什么都不做。
finally: 如果try代码块存在,finally代码块是必须被执行的。即使无法预知的异常发生,finally里的代码也是会被执行的。finally的存在可以避免编程人员在之前代码中写入break,return,continue而引起的错误。即使没有任何异常发生,finally的存在对于程序正常运行也是非常有用的。
public void writeList() {
PrintWriter out = null;
try {
System.out.println("Entering" + " try statement");
out = new PrintWriter(new FileWriter("OutFile.txt"));
for (int i = 0; i < SIZE; i++)
out.println("Value at: " + i + " = " + vector.elementAt(i));
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("Caught ArrayIndexOutOfBoundsException: "
+ e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} finally {
if (out != null) {
System.out.println("Closing PrintWriter");
out.close();
}
else {
System.out.println("PrintWriter not open");
}
}
}
throws:有些情况下,可以在方法内部对异常进行try,catch处理,但是还有的情况下,你在写方法的时候,无法预知使用该方法的人怎样使用,会发生怎样的错误,在这种情况下,最好将异常声明在方法上。
public void writeList() throws IOException, ArrayIndexOutOfBoundsException {
}
try代码块中可以抛出异常,如果try代码块后直接跟catch对其进行捕获,则不用再方法声明中
写throws Exception,如果没有对其进行捕获,则必须在方法声明中写入throws Exception,
否则程序会报错。
异常是可以自定义的。在发生异常的时候如果你想知道发生了什么异常,可以通过自定义的异常查看。自定义异常是通过继承Exception,并重新初始化构造函数来实现的。
/**
毕老师用电脑上课
毕老师初始化有名字,初始化之后又会有电脑
毕老师有讲课功能prelect();
电脑有运行run功能和重启功能rest,这两个功能都是有办法解决的,所以都继承Exception类
state=1 电脑正常运行
state=2 电脑蓝屏
state=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//建议你最好规范写法,电脑的英文是computer而不是compluter
{
private static int state=2;
public void run()throws LanPingException,MaoYanException
{
if(state==1)
System.out.println("电脑正常运行");
if(state==2)
throw new LanPingException("电脑蓝屏啦");
if(state==3)
throw new MaoYanException(("电脑冒烟啦");
}
public void reset()
{
System.out.println("电脑重启");//这个地方不要调用run方法,因为你的方法声明要抛异常,如果调用还要对其进行try...catch
state=1;
}
}
class Teacher
{
private String name;
private Computer cmp=null;//这个地方最好设为空,避免空指针异常
Teacher(String name)
{
this.name=name;
cmp=new Computer();
}
public void prelect() throws NoPlanException//这里要抛给主函数异常
{
try
{
cmp.run();
System.out.println(name+"开课了");
}
catch (LanPingException e)
{
cmp.reset();//此时state=1
prelect();//再次调用prelect()方法,电脑正常
}
catch(MaoYanException e)
{
throw new NoPlanException("课时无法继续"+e.getMessage());
}
}
}
class TeacherDemo
{
public static void main(String[] args)
{
Teacher t = new Teacher("毕老师");
try
{
t.prelect();
}
catch (NoPlanException e)
{
System.out.println(e.toString());
System.out.println("换老师或者放假");
}
}
}
RuntimeException可以不编写异常处理的程序代码,依然可以编译成功,它是在程序运行时才发生的,其他
异常必须编写异常处理的程序代码,或抛出异常。
如果这个异常子类无法处理,已经影响了子类方法的具体运算,这时可以在子类方法中,通过throw抛出
RuntimeException异常或者其子类,这样,子类的方法上是不需要throws声明的。
学习感悟:遇到异常时,为了节省时间我一般采取抛出的方式,但是这种方式对于处于异常是不好的,因为最后异常抛给了虚拟机,虚拟机也没有办法只好自动退出。所以最好的办法还是用try catch处理。