Означает ли это, что если у меня есть последнее поле в классе A типа B, в котором, в свою очередь, есть последнее поле типа Integer, то окончательное замораживание поля для экземпляра класса A завершается только после последнегозамораживание поля для bc уже произошло?
Я думаю, я бы осторожно сказал, что окончательное замораживание поля в этом случае означает, что когда вы создаете экземпляр A и безопасно публикуете его,другие объекты никогда не увидят неинициализированное значение для b или c.
Я бы также сказал, что когда вы создаете экземпляр B внутри A, другой код инициализации внутри A никогда не увидит неинициализированное значение для c.
Один случай, когда я столкнулся с реальными вопросами относительно окончательного замораживания поля, это, например, класс, который содержит (изменяемый) HashMap, предназначенный только для чтения, инициализированный во время построения:
public class DaysOfWeek {
private final Map daysOfWeek = new HashMap();
public DaysOfWeek() {
// prepopulate my map
daysOfWeek.put(0, "Sunday");
daysOfWeek.put(1, "Monday");
// etc
}
public String getDayName(int dayOfWeek) {
return daysOfWeek(dayOfWeek);
}
}
Здесь возникает вопрос: при условии, что этот объект безопасно опубликован, и, учитывая, что здесь нет синхронизации, безопасно ли для других потоков вызывать getDayName ()?Ответ - да, потому что окончательное замораживание поля гарантирует, что HashMap и все, что из него доступно (здесь это просто строки, но могут быть произвольно сложными объектами), будут заморожены в конце построения.[Если вы действительно хотите изменить эту карту после построения, вам понадобится явная синхронизация вокруг операций чтения и записи.] Вот блог длиной , исследующий тему, и просмотрите комментарии, чтобы найти интересные ответы от таких людей, как Брайан.Гетц.
Кстати, я автор рефкарты