import java.lang.invoke.*; public class AlmostFinal { private final MethodHandle getter; private SwitchPoint switchPoint; private VolatileCallSite callSite; public AlmostFinal(T initial) { switchPoint = new SwitchPoint(); callSite = new VolatileCallSite(MethodType.genericMethodType(0)); getter = switchPoint.guardWithTest(MethodHandles.constant(Object.class, initial), callSite.dynamicInvoker()); } public T value() { try { return (T) getter.invokeExact(); } catch (Throwable t) { throw new Error(t); // Shouldn't happen } } public synchronized void setValue(T val) { final SwitchPoint[] invalid = { switchPoint }; switchPoint = new SwitchPoint(); final VolatileCallSite previousSite = callSite; callSite = new VolatileCallSite(MethodType.genericMethodType(0)); previousSite.setTarget(switchPoint.guardWithTest(MethodHandles.constant(Object.class, val), callSite.dynamicInvoker())); SwitchPoint.invalidateAll(invalid); } }