JVM вызывает финализаторы для неинициализированных объектов? [Дубликат]

Следуя указаниям MartinR и Boecko:

$ curl -s 'http://twitter.com/users/username.json' | python -mjson.tool

Это даст вам очень дружелюбный результат. Очень удобно:

$ curl -s 'http://twitter.com/users/username.json' | python -mjson.tool | grep my_key
15
задан Philip Couling 23 January 2013 в 17:33
поделиться

3 ответа

Мой тест показывает, что он может

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);
    }
}

печатать

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

на Java HostSpot Client VM 1.7.0_03

11
ответ дан Evgeniy Dorofeev 18 August 2018 в 01:08
поделиться
  • 1
    Это очень полезно! Не могли бы вы внести изменения в свой ответ, какой JVM вы попробовали, и я приму это. Большое спасибо! – Philip Couling 23 January 2013 в 17:45
  • 2
    это потому, что подразумеваемый super () не выбрасывал исключение. – Jason Pyeron 13 June 2014 в 14:52

Согласно разделу 12.6.1. Реализация Finalization JLS:

Объект o не является окончательным до тех пор, пока его конструктор не вызовет конструктор для Object on o и этот вызов не завершится успешно (то есть, не выбрасывая исключение).

Если ваш конструктор выдает исключение после , конструктор объекта завершается, ваш объект должен быть финализирован, поэтому finalize() все равно можно вызвать.

В примере 12.5 есть хороший пример перехода через конструкцию объекта. Создание экземпляров нового класса , который точно показывает, когда вызывается конструктор объекта.

10
ответ дан Bill the Lizard 18 August 2018 в 01:08
поделиться
  • 1
    Это означает, что в классе X X () {super ();} вызов super () объекта Object завершен без исключения. Класс Object имеет код клевания для регистрации распределения кучи, выделенного новым, для сбора мусора. – Jason Pyeron 13 June 2014 в 14:38
  • 2
    Стоит отметить, что вышеприведенное замечание (определение finalizable ) появилось в третьем выпуске JLS (Java 1.5), но Java 1.5 все еще допускает запуск финализатора, хотя функция Object конструктор никогда не вызывается (см. здесь ). Эта ошибка была зафиксирована только в Java 1.6. – Bass 3 July 2018 в 17:21
  • 3
    @Bass, и есть даже возможность JVM, чтобы включить старое поведение, чье точное имя я не помню, к сожалению. – Holger 4 July 2018 в 06:49
  • 4
    @Holger Спасибо! Я считаю, что это RegisterFinalizersAtInit . – Bass 4 July 2018 в 11:58

Чтобы продемонстрировать более четко:

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);
    }
}

печатает

java.lang.RuntimeException
    at test.Test1.<init>(Test1.java:13)
    at test.Test1.main(Test1.java:24)
test.Test1@6dc8f3cd
finalized
1
ответ дан Jason Pyeron 18 August 2018 в 01:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: