+
+ /*
+ * Use identity comparison for keys and allow classes to be GCd themselves.
+ *
+ * Since codecs can (and typically do) hold a direct or indirect strong reference to the class, they need to be also
+ * accessed via reference. Using a weak reference could be problematic, because the codec would quite often be only
+ * weakly reachable. We therefore use a soft reference, whose implementation guidance is suitable to our use case:
+ *
+ * "Virtual machine implementations are, however, encouraged to bias against clearing recently-created or
+ * recently-used soft references."
+ */
+ private static final LoadingCache<Class<?>, EncapsulatedValueCodec> CACHE = CacheBuilder.newBuilder().weakKeys()
+ .softValues().build(new CacheLoader<>() {
+ @Override
+ public EncapsulatedValueCodec load(final Class<?> key) throws ReflectiveOperationException {
+ final Method m = key.getMethod(BindingMapping.SCALAR_TYPE_OBJECT_GET_VALUE_NAME);
+ final Lookup lookup = MethodHandles.publicLookup();
+ final MethodHandle getter = lookup.unreflect(m).asType(OBJ_METHOD);
+ final Class<?> valueType = m.getReturnType();
+ final MethodHandle constructor = lookup.findConstructor(key,
+ MethodType.methodType(void.class, valueType)).asType(OBJ_METHOD);
+ return new EncapsulatedValueCodec(constructor, getter, valueType);
+ }
+ });
+