Якщо ви робите fooстатичний, ви повинні ініціалізувати його в конструкторі класу (або в рядку, де ви його визначаєте), як у наступних прикладах.
Конструктор класів (не примірник):
private static final List foo;
static
{
foo = new ArrayList();
}
В лінію:
private static final List foo = new ArrayList();
Проблема тут полягає не в тому, як finalпрацює модифікатор, а в тому, як staticпрацює модифікатор.
finalМодифікатор нав'язує ініціалізацію довідки за часом виклику конструктор Завершує (тобто ви повинні ініціалізувати його в конструкторі).
Коли ви ініціалізуєте атрибут in-line, він ініціалізується перед запуском коду, який ви визначили для конструктора, і ви отримаєте такі результати:
- якщо
foo є static, foo = new ArrayList()буде виконуватися до того , як static{}конструктор ви визначили для свого класу виконуються
- якщо
foo ні static, foo = new ArrayList()то буде виконано до запуску конструктора
Якщо ви не ініціюєте атрибут в рядку, final модифікатор примушує його ініціалізувати, і ви повинні зробити це в конструкторі. Якщо у вас також є staticмодифікатор, конструктор, у якому вам доведеться ініціалізувати атрибут, - це блок ініціалізації класу:static{} .
Помилка, яку ви отримуєте у своєму коді, полягає в тому, що static{} виконується під час завантаження класу, до моменту інстанцізації об'єкта цього класу. Таким чином, ви не будете ініціалізуватись fooпри створенні класу.
Подумайте про static{}блок як конструктор для об'єкта типуClass . Тут потрібно виконати ініціалізацію static finalатрибутів класу (якщо це не зроблено вбудовано).
Бічна примітка:
The final Модифікатор запевняє константні-Несс тільки для примітивних типів і посилань.
Коли ви оголошуєте finalоб'єкт, ви отримуєте цеfinal посиланням на цей об’єкт, але сам об'єкт не є постійним.
Чого ви дійсно досягаєте при оголошенні finalатрибута, це те, що, коли ви оголосите об’єкт для вашої конкретної мети (наприклад, те, final Listщо ви оголосили), для цього буде використаний той і лише цей об'єкт: ви не зможете змінитись List fooна інший List, але ви все одно можете змінити свої дані List, додаючи / видаляючи елементи (використовувані Listвами будуть ті ж самі, лише зі зміненим вмістом).