Java - странное статическое поведение String - новая String ( "xxx" ) vs "xxx" - программирование
Подтвердить что ты не робот

Java - странное статическое поведение String - новая String ( "xxx" ) vs "xxx"

public class Test {

    private static final String str1 = new String("en");
    private static Test instance = initInstance();

    private static final String str2 = new String("en");
    private static final String str3 = "en";

    private Test() {
    }

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

    private static Test initInstance() {
        instance = new Test();
        System.out.println(str1 + ',' + str2 + ',' + str3);
        return instance;
    }
}

Теоретически со статикой повсюду он должен приводить к "en, en, en".

Результат: "en, null, en"

Ожидаемое: "en, null, null" (поскольку я обнаружил, что порядок статики имеет значение)

Может ли кто-нибудь объяснить это? В чем разница между "en" и новой строкой ( "en" )?

4b9b3361

Ответ 1

Да. Во время вызова метода str2 еще не инициализируется (поля инициализируются в порядке объявления), а str3 - константа времени компиляции.

Константы времени компиляции встроены компилятором в файле класса. новый String ( ".." ) не является константой, потому что он использует конструктор.

Строковые константы определяются строковым литералом: "", и они помещаются в пул строк в экземпляре jvm, чтобы они были повторно использованы. В отличие от этого, использование нового String (..) создает новый экземпляр, и поэтому его следует избегать.

Ответ 2

Это происходит потому, что сначала инициализируются переменные класса, инициализированные константами, и только тогда выполняются более сложные инициализаторы (например, ваши выражения с использованием new String()) (они затем выполняются в порядке источника). См. JLS & sect; 8.3.2.1:

8.3.2.1. Инициализаторы для переменных класса

[...]

Во время выполнения поля static, которые являются final и которые инициализируются постоянными выражениями (§15.28) сначала инициализируются (§12.4.2). Это также относится к таким полям в интерфейсах (§9.3.1). Эти поля являются "константами", которые никогда не будут иметь начальные значения по умолчанию (§4.12.5) даже при использовании коварных программ (§13.4.9).

Ответ 3

1. Это потому, что str3 = "en" is a String literal in literal pool, and str1 = new String("en") is a String object в пуле объектов String.

2. Поскольку "en" является литералом, то есть константой, он будет инициализирован в начале.

3. Его также называют Constant Folding, предварительно вычисляя константы для выполнения быстрее.