Список строк всегда имеет значение null

#java

#java

Вопрос:

Я пытаюсь инициализировать список строк как private static final, но я всегда получаю значение l как null , и если я объявляю его, как показано во втором фрагменте кода, он работает.

То, что я пытаюсь сделать, это добавить элементы списка, который я объявляю, в trie, чтобы позже соответствовать некоторому шаблону…

Любые мысли о том, почему значение null в первом примере и как я могу это исправить? Спасибо

 public class Myclass {
    public static final Myclass INSTANCE = new Myclass();

    private static final List<String> l = Arrays.asList("ofo", "oof", "foo");

    private Trie trie;

    private Myclass() {
        trie = buildTrie();
    }

    private Trie buildTrie() {
        TrieBuilder builder = Trie.builder();
        Iterator<String> iterator = l.iterator();
        while (iterator.hasNext()) {
            builder.addKeyword(iterator.next());
        }
        return builder.build();
    }
}
 
 public class Myclass {
    public static final Myclass INSTANCE = new Myclass();
    private Trie trie;

    private Myclass() {
        List<String> l = Arrays.asList("ofo", "oof", "foo");
        trie = buildTrie();
    }

    private Trie buildTrie() {
        TrieBuilder builder = Trie.builder();
        Iterator<String> iterator = l.iterator();
        while (iterator.hasNext()) {
            builder.addKeyword(iterator.next());
        }
        return builder.build();
    }
}
 

Комментарии:

1. Во втором случае l он не входит в область действия in buildTrie() , поэтому он просто не будет компилироваться.

2. @khelwood Готово ! Спасибо

3. Кроме того, использование расширенного цикла for было бы намного проще, чем итератор.

4. это работает для второго случая, моя проблема связана с первым случаем, когда список l всегда равен нулю

Ответ №1:

 public class Myclass {
    public static final Myclass INSTANCE = new Myclass();

    private static final List<String> l = Arrays.asList("ofo", "oof", "foo");
 

Статическая инициализация выполняется в порядке объявления. Это означает, что INSTANCE инициализируется раньше l , поэтому конструктор Myclass считывает неинициализированное значение l .

Обратный порядок объявлений:

 public class Myclass {
    private static final List<String> l = Arrays.asList("ofo", "oof", "foo");

    public static final Myclass INSTANCE = new Myclass();
 

Или, если вы на самом деле не требуете l иного, рассмотрите возможность передачи его в качестве параметра конструктора.

Комментарии:

1. Спасибо, Энди! что касается вашего последнего комментария, вы рекомендуете использовать цикл for вместо итератора? (в более сложном примере или больших данных)

2. @Slach enhanced для циклов использует внутренний итератор. Это просто более чистый синтаксис.