Для круговых неизменяемых:
class Foo
{
final Object param;
final Foo other;
Foo(Object param, Foo other)
{
this.param = param;
this.other = other;
}
// create a pair of Foo's, A=this, B=other
Foo(Object paramA, Object paramB)
{
this.param = paramA;
this.other = new Foo(paramB, this);
}
Foo getOther(){ return other; }
}
// usage
Foo fooA = new Foo(paramA, paramB);
Foo fooB = fooA.getOther();
// publish fooA/fooB (unsafely)
Вопрос в том, что this
из fooA
просочилась внутрь конструктора, является ли fooA
по-прежнему безопасным для потоков? То есть, если другой поток читает fooB.getOther().param
, гарантированно ли он увидит paramA
? Ответ - да, поскольку this
не просочился в другой поток до действия freeze ; мы можем установить порядки hb / dc / mc, требуемые спецификацией, чтобы доказать, что paramA
является единственным видимым значением для чтения.
Вернуться к исходному вопросу. На практике всегда есть ограничения, помимо чисто технических. Инициализация всего внутри конструктора не обязательно является лучшим вариантом для проектирования, учитывая все инженерные, эксплуатационные, политические и другие человеческие причины.
Вы когда-нибудь задумывались над тем, почему нам надоело думать, что это великая высшая идея?
Более глубокой проблемой является Java. не хватает общего дешевого средства для безопасной публикации, которое дешевле, чем изменчивое. У Java это есть только для final
полей; по какой-то причине этот забор недоступен.
Теперь final
имеет два независимых значения: 1-е, что последнее поле должно быть назначено ровно один раз; Во-вторых, семантика памяти безопасной публикации. Эти два значения не имеют ничего общего друг с другом. Это довольно запутанно, чтобы связать их вместе. Когда люди нуждаются во втором значении, они также вынуждены принимать первое значение. Когда 1-е очень неудобно для достижения в дизайне, люди задаются вопросом, что они сделали неправильно - не понимая, что это неправильно сделала Java.
Объединение двух значений под одним final
делает его двойным плюс хорошим, так что, очевидно, у нас больше оснований и мотивации для использования final
. Более зловещая история - на самом деле мы вынуждены использовать ее, потому что нам не дают более гибкого выбора.