Семантика конечного поля и десериализация с setAccessible(true)

Согласно модели памяти Java, final поле, инициализированное в конструкторе объекта, не подлежащего дальнейшим модификациям, гарантированно будет иметь правильное значение для каждого читающего его потока, даже если сам объект был опубликован с гонками данных.

В JLS говорится о 17.5.3 Последующая модификация конечных полей, и туманно указано, что

реализация может предоставить способ выполнения блока кода в безопасном контексте конечного поля.

При этом, похоже, не определена семантика таких модификаций, ни где именно должен существовать этот безопасный контекст конечного поля, ни как его определить (т.е. JLS, похоже, не дает никаких гарантий относительно последующей модификации конечных полей).

Должен сказать, что я не до конца понял частичные порядки dereferences() и mc(), а также поведение действия freeze, которое происходит после любой модификации конечного поля (как начального значения, приписанного ему, так и последующих модификаций).

Исходя из этого контекста, я хочу знать следующее: как фреймворк (де)сериализации, такой как Gson, может гарантировать, что десериализованные объекты, содержащие конечные поля, должным образом инициализированные в конструкторе, не будут представлять проблему видимости потока?

Например, рассмотрим этот класс:

class X {
  private final String s;
  public X(final String s) { this.s = s; }
  @Override public String toString() { return s; }
}

И следующий код:

final Gson gson = new Gson();
X x = gson.fromJson(gson.toJson(new X("abc")), X.class);
System.out.println(x);
// prints abc

Зайдя в метод fromJson с отладчиком, я вижу, что sun.misc.Unsafe используется для выделения экземпляра X без вызова его конструктора, а поля setAccessible(true), и, наконец, они устанавливаются.

И это только в Sun'овских (или совместимых) JVM! Похоже, что в Gson есть код, специфичный для нескольких версий Android.

Итак, существуют ли какие-либо гарантии потокобезопасности, связанные с этими десериализованными конечными полями, точно так же, как это было бы с экземпляром X, созданным с помощью new X("abc")? Если да, то откуда берется эта гарантия?

Спасибо!

9
задан Bruno Reis 5 October 2011 в 01:30
поделиться