Видимость конечных полей, не заданных в конструкторе [дубликат]

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

54
задан Joachim Sauer 11 February 2013 в 11:52
поделиться

5 ответов

Если вы посмотрите на декомпилированную версию файла класса

class X {
    Y b;

    X() {
        b = new Y();
        System.out.print("X");
    }
}

class Y {
    Y() {
        System.out.print("Y");
    }
}

public class Z extends X {

    Y y;

    Z() {
        y = new Y();
        System.out.print("Z");
    }

    public static void main(String args[]) {
        new Z();
    }
}

Вы можете обнаружить, что переменная экземпляра y перемещается внутри конструктора, поэтому последовательность выполнения выглядит следующим образом

  1. Вызов конструктора Z
  2. Он запускает конструктор по умолчанию X
  3. Вызывается первая строка конструктора X new Y().
  4. Печать Y
  5. Печать X
  6. Вызов первой строки в конструкторе Z new Y()
  7. Печать Y
  8. Печать Z

Все переменные экземпляра инициализируются с помощью инструкций конструктора.

49
ответ дан Arun P Johny 24 August 2018 в 07:51
поделиться

Последовательность инициализации задана в JLS 12.5:

1. Сначала выделяется память для нового объекта

2. Затем все переменные экземпляра объекта (включая те, определенные в этом классе и всех его суперклассах) инициализируются значениями по умолчанию

. 3. Наконец, вызывается конструктор.

https://stackoverflow.com/ вопросы / 26552799 / которая-вводные первоклассники по умолчанию-значений-для-экземпляр-переменных-или-супер-конструкторов

-3
ответ дан Community 24 August 2018 в 07:51
поделиться

Когда вы вызываете конструктор, инициализаторы переменной экземпляра запускаются перед телом конструктора. Что вы думаете о выходе программы ниже?

public class Tester {
    private Tester internalInstance = new Tester();
    public Tester() throws Exception {
        throw new Exception("Boom");
    }
    public static void main(String[] args) {
        try {
            Tester b = new Tester();
            System.out.println("Eye-Opener!");
        } catch (Exception ex) {
            System.out.println("Exception catched");
        }
    }
}

Основной метод вызывает конструктор Tester, который выдает исключение. Вы могли бы ожидать, что предложение catch поймает это исключение и выведет Исключение, пойманное . Но если вы попытались запустить его, вы обнаружили, что он ничего не делает, и он выбрасывает StackOverflowError.

0
ответ дан Prototype Chain 24 August 2018 в 07:51
поделиться

Правильный порядок инициализации:

  1. Статические инициализаторы инициализаций и блоки статической инициализации в текстовом порядке, если класс ранее не был инициализирован.
  2. super () в конструкторе, явный или неявный.
  3. Инициализаторы инициализации экземпляра и блоки инициализации экземпляра в текстовом порядке.
  4. Оставшееся тело конструктора после super ().

См. разделы § 2.17.5-6 спецификации виртуальной машины Java .

75
ответ дан user207421 24 August 2018 в 07:51
поделиться

Чтобы прояснить неправильные представления со статикой, я просто обращусь к этой небольшой части кода:

public class Foo {
  { System.out.println("Instance Block 1"); }
  static { System.out.println("Static Block 1"); }
  public static final Foo FOO = new Foo();
  { System.out.println("Instance Block 2"); }
  static { System.out.println("Static Block 2 (Weird!!)"); }
  public Foo() { System.out.println("Constructor"); }
  static public void main(String p[]) {
    System.out.println("In Main");
    new Foo();
  }
}

Сюрприз заключается в том, что выход выглядит следующим образом:

Static Block 1
Instance Block 1
Instance Block 2
Constructor
Static Block 2 (Weird!!)
In Main
Instance Block 1
Instance Block 2
Constructor

Заметим, что у нас есть static {}, который называется после двумя экземплярами {}. это происходит потому, что мы вставляем конструктор в середине, вставляем порядок выполнения при первом вызове конструктора.

Обнаружено это, когда я работал над этим ответом - https://stackoverflow.com /a/30837385/744133.

В основном мы наблюдаем, что это произойдет:

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

Мне нужно исследовать, как сочетание наследования, а также явные и неявные вызовы super и это повлияет на это, и обновит результаты. Это было бы похоже на другие предоставленные ответы, за исключением того, что они ошибались со статической инициализацией.

1
ответ дан YoYo 24 August 2018 в 07:51
поделиться