finally 是不是一定会执行?在finally中return会怎样?

在finally中return会怎样?

public class MyLab {
public String testFinally(){  
    try{  
        return "try";  
    }catch(Exception e){  
        return "catch";  
    }finally{  
        return "finally";  
    }  
} 

public static void main(String[] args) {
    MyLab out = new MyLab();
    System.out.print(out.testFinally());
}
}

结果是:finally

看编译出来的源码:

 public String testFinally()
  {
        String str1;
try{
      str1 = "try";

      return "finally";
}catch (Exception localException){

  String str2 = "catch";
  return "finally"; 
} 
 return "finally";
  }

可以看到try-catch 块里的return "try" 、return "catch"都被替换成return "finally"了。

所以finally里的return 会覆盖try-catch 块中的return。

那是不是说明finally块中的代码就一定会被执行?

不是的,在Java编程思想讲到守护线程(Daemon)时有个例子

import java.util.concurrent.*;  

public class SimpleDaemons implements Runnable{  
public void run{  
    try{  
        System.out.println(“Start daemons”);  
        TimeUtil.SECONDS.sleep(1);  
    }catch(Exception e){  
        System.out.println(“sleep() interrupted”);  
    }finally{  
        System.out.println(“Finally is running”);  

    }  
}  
public static void main(String[] args) throws Exception{  
   Thread daemon = new Thread(new SimpleDaemons());  
   daemon.setDaemon(true);  
   daemon.start();  
}  
} 

输出结果:

Start daemons

Finally块没有执行,如果注释掉daemon.setDaemon(true)设置守护进程这一句代码。

输出结果:

Start daemons  
Finally is running

之所以产生这样的结果原因是,main()是这个程序中唯一的非守护线程,当没有非守护线程在运行时,JVM强制退出终止守护线程的运行。

什么是守护线程

在Java中有两类线程:用户线程 (User Thread)、守护线程 (Daemon Thread)。

所谓守护线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。

用户线程和守护线程两者几乎没有区别,唯一的不同之处就在于虚拟机的离开如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。

在使用守护线程时需要注意一下几点:

(1) 通过Thread对象的setDaemon方法可以设置线程是否为守护线程,通过isDaemon方法可以判断线程对象是否为守护线程。thread.setDaemon(true)必须在thread.start()之前设置,否则会抛出IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。

(2) 在Daemon线程中产生的新线程也是Daemon的。

(3) 守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。

(4)由守护线程创建的线程对象不论有没有通过setDaemon方法显式设置,都是守护线程。

在上面的例子中,所有的非守护线程(main方法)都已经执行完毕,那么守护线程将立即被结束,因此守护线程的finally子句不一定能够执行。这时程序都结束了,finally块代码也就执行不到了。

你可能感兴趣的:(finally 是不是一定会执行?在finally中return会怎样?)