Can finalize be called after a constructor throws an exception?

前端 未结 3 824
青春惊慌失措
青春惊慌失措 2021-01-01 17:06

Are there any details on whether or not an object is cleaned up using finalize() if that object\'s constructor thew an exception.

When this method is ca

相关标签:
3条回答
  • 2021-01-01 17:10

    My test shows that it can

    public class Test1 {
    
        Test1() {
            throw new RuntimeException();
        }
    
        @Override
        protected void finalize() throws Throwable {
            System.out.println("finalized");
        }
    
        public static void main(String[] args) throws Exception {
            try {
                new Test1();
            } catch (RuntimeException e) {
                e.printStackTrace();
            }
            System.gc();
            Thread.sleep(1000);
        }
    }
    

    prints

    java.lang.RuntimeException
        at test.Test1.<init>(Test1.java:13)
        at test.Test1.main(Test1.java:24)
    finalized
    

    it is on Java HostSpot Client VM 1.7.0_03

    0 讨论(0)
  • 2021-01-01 17:15

    According to section 12.6.1. Implementing Finalization of the JLS:

    An object o is not finalizable until its constructor has invoked the constructor for Object on o and that invocation has completed successfully (that is, without throwing an exception).

    If your constructor throws an exception after the Object constructor completes, then your object should be finalizable, so finalize() could still be called.

    There's a good example stepping through object construction in section 12.5. Creation of New Class Instances that shows exactly when the Object constructor is called.

    0 讨论(0)
  • 2021-01-01 17:32

    To demonstrate more clearly:

    public class Test1 {
    
        public static class LifeBoat extends RuntimeException
        {
            private Test1 passenger;
            public Test1 getPassenger(){return passenger;}
            public LifeBoat(Test1 passenger){this.passenger=passenger;}
        }
    
        Test1() {
            super(); //once this is finished, there is an Object to GC per JLS 12.6.1. 
            throw new LifeBoat(this);
        }
    
        @Override
        protected void finalize() throws Throwable {
            System.out.println("finalized");
        }
    
        public static void main(String[] args) throws Exception {
            try {
                new Test1();
            } catch (LifeBoat e) {
                Test1 obj;
                obj=e.getPassenger();
                System.out.println(obj);
            }
            System.gc();
            Thread.sleep(1000);
        }
    }
    

    prints

    java.lang.RuntimeException
        at test.Test1.<init>(Test1.java:13)
        at test.Test1.main(Test1.java:24)
    test.Test1@6dc8f3cd
    finalized
    
    0 讨论(0)
提交回复
热议问题