Нулевое значение иногда возвращается из константы, инициализированной в объявлении. Это ошибка кодирования? - PullRequest
0 голосов
/ 04 января 2019

Нулевое значение иногда возвращается константой, которая инициализируется при объявлении. Является ли значение нулевым или нет, зависит от порядка выполнения другого кода.

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

Правильно:

[STRING, LOCAL_DATE_TIME, INTEGER]

Неправильно:

[STRING, null, INTEGER]

Различные результаты могут быть получены путем добавления или удаления строки кода непосредственно перед печатью. Правильный результат печатается при удалении строки.

Вот основной класс с включенной ошибочной строкой:

package foo;
import tech.tablesaw.api.DateTimeColumn;

class DummyClass {

    public static void main(String[] args) {
        long missing = DateTimeColumn.MISSING_VALUE;
        new DummyPrinter().printColumnTypes();
    }
} 

Когда я закомментирую строку 1 в main, код работает так, как я ожидал.

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

package foo;

import tech.tablesaw.api.ColumnType;
import java.util.Arrays;
import static tech.tablesaw.api.ColumnType.*;

class DummyPrinter {

    void printColumnTypes() {
        System.out.println(Arrays.toString(columnTypes));
    }

    private static final ColumnType[] columnTypes = {
        STRING,
        LOCAL_DATE_TIME,
        INTEGER,
    };
}

Как видите, сам массив является литеральной константой.

Значения, вставленные в массив, также являются константами. Они объявлены в интерфейсе ColumnType в строке, показанной ниже:

DateTimeColumnType LOCAL_DATE_TIME = DateTimeColumnType.INSTANCE;

Источник: [https://github.com/jtablesaw/tablesaw/blob/master/core/src/main/java/tech/tablesaw/api/ColumnType.java]

В этой строке значения задаются другой константой. Этот объявлен в классе с именем DateTimeColumnType, который является одиночным.

Вот код из этого класса, в котором создан Singleton:

public static final DateTimeColumnType INSTANCE =
        new DateTimeColumnType(BYTE_SIZE, "LOCAL_DATE_TIME", "DateTime");

Источник: [https://github.com/jtablesaw/tablesaw/blob/master/core/src/main/java/tech/tablesaw/columns/datetimes/DateTimeColumnType.java]

Это снова статическая конечная (постоянная) переменная. AFAIK, он никогда не должен возвращать ноль. И используемая ею константа интерфейса никогда не должна возвращать ноль.

Итак, вернемся к строке кода, которая включает и выключает ошибку. Насколько я могу судить, влияние этой строки состоит в том, что она заставляет класс DateTimeColumnType загружаться в другом порядке, когда он присутствует, чем когда он отсутствует.

Мой вопрос: есть ли в показанном коде что-либо, что, согласно спецификации языка Java, внесло бы неопределенность в правильность инициализации значения? Другими словами, есть ли ошибка в моем коде, которая вызывает проблему? Если да, то? Или логика инициализации (хотя и сложная) правильна с точки зрения языка?

...