感慨一下,到了现在感觉Java里面很多东西都是模模糊糊,不能这样了,一点点解决吧。
今天看了异常的一些内容,感觉看得很浅,所以晚上写下来,算是巩固,如果后面看到更好的内容,再慢慢加上去。
异常在运行的时候很常见,有时候不运行,编译的时候也会有类似的提示,说要你处理什么什么异常。当程序发生异常的时候,它就退出了,很坑爹。而有了异常处理机制后,即使出现了异常,程序员依然可以处理它,使程序继续运行下去,这样一来,你的程序就有了很大的灵活性以及健壮性。这是我的理解。
提到异常处理,经常听别人说到一些概念,什么try…catch…啦,throws和throw啦,finally啦,还有什么assert,很高端的样子,还是一个个来看吧。
首先来看一下一个最最最常见的异常代码:
public class Demo{ public static void main(String [] args){ int i = 10; int j = 0; System.out.println("************0********"); System.out.println(i/j); System.out.println("**********1***********"); } }程序执行到System.out.println(i/j); 这里就停了,***1***不会输出。
从这就可以看出,程序会在异常发生处停止运行,其后所有代码都不会再执行了。
现在我想让程序无论如何要输出***1***怎么办?
那用try…catch吧!
try{ //可能会发生异常的语句 }catch(异常类型 异常对象){ //处理 }注意一点哦,Java将所有的错误(异常)都封装成了对象。
我们再改写一下代码:
public class Demo{ public static void main(String [] args){ int i = 10; int j = 0; System.out.println("************0********"); try{ System.out.println(i/j); }catch(ArithmeticException e){ e.printStackTrace(); } System.out.println("**********1***********"); } }现在不仅可以显示异常信息,***1***也可以输出了。
注意哦,如果把System.out.println("**********1***********"); 放在try块中依然不可以执行,这是因为程序一直遵循着执行到异常处退出,如果有catch则跳到catch中去处理。
具体来说,在try块中,如果异常发生了,就会产生一个错误(异常)对象,然后去catch中找,这里抛出了是ArithmeticException对象,在catch中找到了,那么就继续在这个catch中处理了。是不是很好用!
下面再说一下finally,其实大家或多或少都用过,在处理文件的时候,或者在连接数据库的时候,关闭文件,关闭连接都是放在finally中,finally是确保无论是否发生异常都一定会执行的语句块。
可是刚刚我们也看到,我们并没有加finally,***1***依然可以执行,是不是?那么我们为什么还要finally?
首先,确定一点,finally是确保1000%一定会执行到的,那么你能确保try…catch…外的语句100%执行吗?显然不可以。
只要稍微改一下上面的代码:
public class Demo{ public static void main(String [] args){ int i = 10; int j = 0; System.out.println("************0********"); try{ Integer.parseInt(""); System.out.println(i/j); }catch(ArithmeticException e){ e.printStackTrace(); } System.out.println("**********1***********"); } }注:Integer.paraseInt("")仅是为了演示,并没有什么用处。
运行上面代码,程序就不会输出***1***了,这是因为程序又抛出了一个新异常: java.lang.NumberFormatException而这个异常我们并未catch,程序执行到Integer.paraseInt("")就已经跪了。
这时候我们可以说,再加一个catch不就OK了!是的,这也是我要说的一点,try后面可以跟着很多catch。但是,注意,你不可能尽善尽美,不可能考虑到所有的状况,因此总有一定的概率会疏忽,一旦出现疏忽,将功亏一篑。
而有了finally,立马就不一样了!(好恶心的台词)
public class Demo{ public static void main(String [] args){ int i = 10; int j = 0; System.out.println("************0********"); try{ Integer.parseInt(""); System.out.println(i/j); }catch(ArithmeticException e){ e.printStackTrace(); }finally{ System.out.println("**********1***********"); } } }嗯,这不就是异常处理三件套么!
try{ //... }catch(XXException e){ //... }catch(XXException e){ //... }catch(XXException e){ //... }catch(XXException e){ //... } //... finally{ //100%会执行 }关于这一部分,还有一点要说的是:
在众多的catch中,放置顺序一定要注意:子类放在父类前面,也就是小的放在大的前面,否则,执行完父类就不执行子类了,也许这不是你想要的结果。
比如:
把Throwable放在第一个,那么后面无论有多少catch都不会被执行了。还有,我这里举得例子很不恰当,Throwable太大了,尽量别真这么做啊!
异常处理相关的最大父类是Throwable,它有两个孩子,一个是Error,一个是Exception。
对于Error来说,不需要我们处理,因为这种错太严重了,比如内存不足什么的,你捕获了也拿它没办法,这种东西JVM会去处理的。
我们要捕获的通常是Exception。
但是对于Exception,也有两种分类:Checked Exception 和UnChecked Exception,在编码中我们都遇到过:
比如我们刚刚遇到的除数为0的问题,就算你不捕获,编译也会通过,这就属于不强制加异常处理的,我们称为UnChecked Exception;
另一类,如果你不加,它就不给你通过的,就属于Checked Exception了,在用Eclipse编码的时候,通常会有提示的。
对于UnChecked Exception主要是Exception众多子类中叫RuntimeException的那一个,这一个Exception通常不会强制的,显然其他的就强制咯。
它们俩给我第一感觉就是,真是像的biang biang声啊。一个个看吧。
先看throws
throws可以在程序的方法声明处使用,(看清是方法),此时可以不在方法中处理任何异常,而交由被调用出处理。
首先,考虑一下,为什么要们要用throws?
在前面我们是将错误直接输出的,而且我们是将处理逻辑直接放在main中的,这是最简单的例子了。那么显然,我们通常是需要把处理逻辑放在某个类的某个函数中的,而这个类很有可能是被别人使用的,刚刚我们是直接将错误输出到控制台,那么你怎么确定使用你类的程序员也想在控制台输出?你怎么知道,他是想按你的方式去处理?很显然,作为类的编写者,无法知道使用者是怎么想的。
这个时候,我们就可以用throws啦!因为我知道这个代码可能会出错,但是我不确定我处理的方式是否符合你的要求,那么,你自己去处理吧!
有了throws,在调用这个方法的地方会强制你try的!哈哈
下面来看一下代码:
public class Demo{ public static void main(String [] args){ ComputeDiv c = new ComputeDiv(); try{ c.div(10,0); }catch(Exception e){ e.printStackTrace(); } } } class ComputeDiv{ public int div(int i, int j) throws Exception{ System.out.println("+++++"); int result = i/j; System.out.println("-----"); return result; } }这里用到了throws,所以需要在main中有try…catch…,可是这里出现一个问题,----无法输出。这是因为i/j处发生了异常,开动脑筋,处理异常后就可以输出了,那么我加try…catch…吧!额,好像也不行,加了之后,throws啥?要那个没用了啊!这个时候,就引出了下面我们要讲的:throw
throw一般和throws结合使用,在程序中人为的抛出一个异常,嗯,似乎刚刚的问题可以解决了!
看代码:
public class Demo{ public static void main(String [] args){ ComputeDiv c = new ComputeDiv(); try{ c.div(10,0); }catch(Exception e){ e.printStackTrace(); } } } class ComputeDiv{ public int div(int i, int j) throws Exception{ System.out.println("+++++"); int result; try{ result = i/j; }catch(Exception e){ throw e; }finally{ /* 不把这句放在finally内也不会显示的哦!看出finally重要性了吧 */ System.out.println("-----"); } return result; } }断言,其实我也不是很懂。因为没怎么用过。大致会用吧。
比如:
public class Demo{ public static void main(String [] args){ int i = 1; assert i == 10; } }用的时候,记得加-ea。
有了异常处理机制,可以使得我们的程序更加灵活机动一些。
try…catch…finally三件套,throws与throw是两件套。完毕。
转载于:https://www.cnblogs.com/marsdu/p/3337579.html