What are the circumstances under which a finally {} block will NOT execute?

前端 未结 9 2046
没有蜡笔的小新
没有蜡笔的小新 2020-11-30 01:45

In a Java try{} ... catch{} ... finally{} block, code within the finally{} is generally considered \"guaranteed\" to run regardless of what occurs

9条回答
  •  感动是毒
    2020-11-30 02:41

    If you call System.exit() the program exits immediately without finally being called.

    A JVM Crash e.g. Segmentation Fault, will also prevent finally being called. i.e. the JVM stops immediately at this point and produces a crash report.

    An infinite loop would also prevent a finally being called.

    The finally block is always called when a Throwable is thrown. Even if you call Thread.stop() which triggers a ThreadDeath to be thrown in the target thread. This can be caught (it's an Error) and the finally block will be called.


    public static void main(String[] args) {
        testOutOfMemoryError();
        testThreadInterrupted();
        testThreadStop();
        testStackOverflow();
    }
    
    private static void testThreadStop() {
        try {
            try {
                final Thread thread = Thread.currentThread();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        thread.stop();
                    }
                }).start();
                while(true)
                    Thread.sleep(1000);
            } finally {
                System.out.print("finally called after ");
            }
        } catch (Throwable t) {
            System.out.println(t);
        }
    }
    
    private static void testThreadInterrupted() {
        try {
            try {
                final Thread thread = Thread.currentThread();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        thread.interrupt();
                    }
                }).start();
                while(true)
                    Thread.sleep(1000);
            } finally {
                System.out.print("finally called after ");
            }
        } catch (Throwable t) {
            System.out.println(t);
        }
    }
    
    private static void testOutOfMemoryError() {
        try {
            try {
                List bytes = new ArrayList();
                while(true)
                    bytes.add(new byte[8*1024*1024]);
            } finally {
                System.out.print("finally called after ");
            }
        } catch (Throwable t) {
            System.out.println(t);
        }
    }
    
    private static void testStackOverflow() {
        try {
            try {
                testStackOverflow0();
            } finally {
                System.out.print("finally called after ");
            }
        } catch (Throwable t) {
            System.out.println(t);
        }
    }
    
    private static void testStackOverflow0() {
        testStackOverflow0();
    }
    

    prints

    finally called after java.lang.OutOfMemoryError: Java heap space
    finally called after java.lang.InterruptedException: sleep interrupted
    finally called after java.lang.ThreadDeath
    finally called after java.lang.StackOverflowError
    

    Note: in each case the thread kept running, even after SO, OOME, Interrupted and Thread.stop()!

提交回复
热议问题