Consider a volatile reference 'cfg' to an immutable config object holding plain (non-final) fields. A writer publishes a fully-built object via 'cfg = newCfg'. A reader does 'Config c = cfg; read c.timeout;'. Why are the plain fields safely visible?
class Config { int timeout; } // plain field
volatile Config cfg;
// writer: Config x = new Config(); x.timeout = 30; cfg = x;
// reader: Config c = cfg; int t = c.timeout;