Нулевое значение иногда возвращается константой, которая инициализируется при объявлении. Является ли значение нулевым или нет, зависит от порядка выполнения другого кода.
Я строю массив, который содержит объекты, которые были инициализированы как константы. Затем я печатаю массив. Иногда все значения инициализируются правильно, иногда нет, как показано в выходных данных ниже.
Правильно:
[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, внесло бы неопределенность в правильность инициализации значения? Другими словами, есть ли ошибка в моем коде, которая вызывает проблему? Если да, то? Или логика инициализации (хотя и сложная) правильна с точки зрения языка?