本篇运用Java讲解了一下try-catch-finally语句的作用
适用于其它支持trycatch的语言,如php
语句的基本形式:
try{
//代码
}catch(Exception e){
//异常处理
}
这可以保证你的程序出现异常状态后可以继续运行下去.例如出现了除数为0的情况,如果没有这个语句,程序就会直接崩溃,而使用了这个语句,不仅程序可以运行下去,还可以知道程序的异常之处.
测试如下代码:
public class text {
public static void main(String[] args)
{
try {
int a;
a=1/0;
System.out.println(a);
}catch(Exception e){
System.out.println("报错");
}
System.out.println("I AM ALIVE!");
}
}
运行该代码后,会输出
报错
I AM ALIVE!
可见程序在运行过程中虽然出现了"1/0"这种会使程序崩溃的情况,但是程序并没有崩溃,而是继续运行下去了.
那么如何知晓程序究竟为什么会崩溃呢?其实在刚才的代码里,"catch(Exception e)"这句的意思就是把错误信息储存在e里了.所以我们只需要输出e即可.
运行如下代码:
public class text {
public static void main(String[] args)
{
try {
int a;
a=1/0;
System.out.println(a);
}catch(Exception e){
System.out.println("报错");
System.out.println(e);
}
System.out.println("I AM ALIVE!");
}
}
输出结果:
报错
java.lang.ArithmeticException: / by zero
I AM ALIVE!
说明报错原因是除数为0.
当然我们还能知晓更多信息,将刚才代码中的"System.out.println(e);"这一句改为"e.printStackTrace();",再运行程序,输出如下:
报错
java.lang.ArithmeticException: / by zero
at text.main(text.java:9)
I AM ALIVE!
通过输出的第三行我们可以知晓是在代码的第九行出现了错误.
知晓错误信息后,如果我们不想改动try{}里的代码,而是想让它在出错后运行另一种方法该怎么办呢?只需要在catch(Exception e){}里加入你想要的方法就行了.
还有另一个语句"finally{}",通常放在catch{}之后,作用为无论有没有报错,都最终运行finally{}里面的方法.也许有人会说为什么不把方法直接放在catch{}之后而要加个finally{},接下来将会说明.
首先我们来测试一下finally对于整个函数的作用
运行如下代码:
public class text {
public void mtry(){ //这是一个自定义方法
String a,b;
try {
a="try";
b="Ttry";
}catch(Exception e){
a="catch";
b="Ccatch";
}finally {
a="finally";
b="Ffinally";
}
System.out.println(a);
System.out.println(b);
}
public static void main(String[] args){
text te=new text();//这步是让text类调用自己
te.mtry();//使用text类的mtry方法
}
}
运行这个代码后,会输出:
finally
Ffinally
说明即使try{}语句内没有报错,程序还是运行了finally{},使ab重新赋值.
接下来我们让try{}强行报错:
在try{}的花括号里添加
int x=1/0;
无疑这样会让try报错,运行后会输出:
finally
Ffinally
说明即使在try报错,运行了catch语句后,finally语句还是最终运行了.
虽然finally语句无论如何都会运行,但我们可以使用一些其它方法来控制它,以达到我们的目的.
在try的花括号里的最后加入
return a;
再对程序进行一些改动,变成如下这样
public class text {
public String mtry(){
String a,b;
try {
a="try";
b="Ttry";
return a;
}catch(Exception e){
a="catch";
b="Ccatch";
}finally {
a="finally";
b="Ffinally";
System.out.println("Finally!");
}
System.out.println(a);
System.out.println(b);
return a;
}
public static void main(String[] args){
String a;
text te=new text();
a=te.mtry();
System.out.println("returned: "+a);
}
}
大家先猜猜运行后会输出什么,再往下看.
你猜的是不是
returned: try
如果是,恭喜你,你错了.
真正运行后会输出:
Finally!
returned: try
按一般我们对函数的理解,在try语句中a,b赋值完毕,而且没有报错,应该会直接return a.但是finally是特殊的.它的运行时间为try{}catch{}被关闭时,即运行完成后,但它会在return执行前执行,执行完后才会return.
我们可以再对程序进行一些改动来理解.再finally的大括号中的最后再加入
return a;
如果你的代码没有写错,那么上面那个程序的这段:
System.out.println(a);
System.out.println(b);
return a;
应该会报错:"unreachable code",意思就是无论如何,这段代码永远不可能被执行.我们姑且先将其注释掉.
改动完成后,代码应当是这样的:
public class text {
public String mtry(){
String a;
try {
a="try";
return a;
}catch(Exception e){
a="catch";
}finally {
a="finally";
System.out.println("Finally!");
return a;
}
/*System.out.println(a);
return a;*/
}
public static void main(String[] args){
String a;
text te=new text();
a=te.mtry();
System.out.println("returned: "+a);
}
}
然后我们再运行,你应该猜到会输出什么了,输出结果如下:
Finally!
returned: finally
而我们都清楚,try{}确实被运行且没报错,但是函数却return了finally,说明finally的return的执行还要在try的return执行之前.
要是你还不信try{}已经被运行了,可以在里面再加一个输出来鉴定.
若try报错,运行了catch语句,其实也和上面的道理类似,现在令try强行报错,并且在catch里加入return a,然后我们再试试
public class text {
public String mtry(){
String a;
try {
a="try";
int x=1/0;
return a;
}catch(Exception e){
a="catch";
return a;
}finally {
a="finally";
System.out.println("Finally!");
return a;
}
/*System.out.println(a);
return a;*/
}
public static void main(String[] args){
String a;
text te=new text();
a=te.mtry();
System.out.println("returned: "+a);
}
}
运行结果如下:
Finally!
returned: finally
综上所诉,我们可以通过将try{}catch{}finally{}写在自定义方法里并用return来更好的控制整个语句的运行.
然而还有一点疑惑的地方:既然在finally{}内将a赋值了,为何还return了在try语句里赋值的a?
我们不妨在finally里面输出a,同时将finally里的return删掉/注释掉.
运行如下代码:
public class text {
public String mtry(){
String a;
try {
a="try";
return a;
}catch(Exception e){
a="catch";
return a;
}finally {
a="finally";
System.out.println(a);
}
}
public static void main(String[] args){
String a;
text te=new text();
a=te.mtry();
System.out.println("returned: "+a);
}
}
输出:
finally
returned: try
为何两个a会不同?其实我也很疑惑这一点,经过百度,大概是这样的:
在try运行到return a这一步时,同时运行了finally,但此时try中要return什么其实已经确定了,程序已经自动将要return的值转存到另一个地方了,所以finally对a进行改动,并不影响整个函数的返回值,除非直接在finally中return另一个东西.
而刚才还遗留的两个问题也可以解决了:
1) 为何不将finally{}内的代码直接写在catch{}后面: 因为有时候我们需要单独操作某个变量,而不改动其它变量,就需要finally出场了.
2) 为何刚才会出现"unreachable code"的报错字样: 因为finally无论如何都会运行,所以在finally里的return必定会运行,自然不可能运行到下一个语句.由此我们可以知道,尽量不要在finally中添加return,否则可能导致一些莫名其妙的错误.
参考资料:
https://www.cnblogs.com/aigongsi/archive/2012/04/19/2457735.html
https://www.cnblogs.com/hyzxx/p/5151911.html
我的话,就一般是
main(){
try{
程序全部qwq
}catch{
忽略全部错误辣
}
}