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

前端 未结 9 1997
没有蜡笔的小新
没有蜡笔的小新 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:34

    Infinite loop in the try block.

    Corrupt RAM? Program no longer runs as written? I've actually debugged that once on a DOS machine.

    0 讨论(0)
  • 2020-11-30 02:39

    The only times finally won't be called are:

    if the power turns off

    1. if you call System.exit()
    2. if the JVM crashes first
    3. if there is an infinite loop in the try block
    4. if the power turns off
    0 讨论(0)
  • 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<byte[]> bytes = new ArrayList<byte[]>();
                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()!

    0 讨论(0)
提交回复
热议问题