methods, Class> mixInCls)
{
diff --git a/src/main/java/tools/jackson/databind/ser/BeanPropertyWriter.java b/src/main/java/tools/jackson/databind/ser/BeanPropertyWriter.java
index 74871c1123..16d757352f 100644
--- a/src/main/java/tools/jackson/databind/ser/BeanPropertyWriter.java
+++ b/src/main/java/tools/jackson/databind/ser/BeanPropertyWriter.java
@@ -1,6 +1,8 @@
package tools.jackson.databind.ser;
import java.lang.annotation.Annotation;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
@@ -23,6 +25,11 @@
import tools.jackson.databind.util.Annotations;
import tools.jackson.databind.util.ClassUtil;
import tools.jackson.databind.util.NameTransformer;
+import tools.jackson.databind.util.internal.UnreflectHandleSupplier;
+
+import static java.lang.invoke.MethodType.methodType;
+
+import static tools.jackson.databind.util.ClassUtil.sneakyThrow;
/**
* Base bean property handler class, which implements common parts of
@@ -106,20 +113,10 @@ public class BeanPropertyWriter
protected final AnnotatedMember _member;
/**
- * Accessor method used to get property value, for method-accessible
- * properties. Null if and only if {@link #_field} is null.
- *
- * `transient` (and non-final) only to support JDK serializability.
+ * Accessor method used to get property value.
+ * Wrapped in a holder since MethodHandle is not serializable.
*/
- protected transient Method _accessorMethod;
-
- /**
- * Field that contains the property value for field-accessible properties.
- * Null if and only if {@link #_accessorMethod} is null.
- *
- * `transient` (and non-final) only to support JDK serializability.
- */
- protected transient Field _field;
+ protected final GetterHolder _accessor = new GetterHolder();
/*
/**********************************************************************
@@ -216,18 +213,6 @@ public BeanPropertyWriter(BeanPropertyDefinition propDef,
_typeSerializer = typeSer;
_cfgSerializationType = serType;
- if (member instanceof AnnotatedField) {
- _accessorMethod = null;
- _field = (Field) member.getMember();
- } else if (member instanceof AnnotatedMethod) {
- _accessorMethod = (Method) member.getMember();
- _field = null;
- } else {
- // 01-Dec-2014, tatu: Used to be illegal, but now explicitly allowed
- // for virtual props
- _accessorMethod = null;
- _field = null;
- }
_suppressNulls = suppressNulls;
_suppressableValue = suppressableValue;
@@ -256,8 +241,6 @@ protected BeanPropertyWriter() {
_typeSerializer = null;
_cfgSerializationType = null;
- _accessorMethod = null;
- _field = null;
_suppressNulls = false;
_suppressableValue = null;
@@ -284,8 +267,6 @@ protected BeanPropertyWriter(BeanPropertyWriter base, PropertyName name) {
_declaredType = base._declaredType;
_member = base._member;
- _accessorMethod = base._accessorMethod;
- _field = base._field;
_serializer = base._serializer;
_nullSerializer = base._nullSerializer;
@@ -311,8 +292,6 @@ protected BeanPropertyWriter(BeanPropertyWriter base, SerializedString name) {
_member = base._member;
_contextAnnotations = base._contextAnnotations;
_declaredType = base._declaredType;
- _accessorMethod = base._accessorMethod;
- _field = base._field;
_serializer = base._serializer;
_nullSerializer = base._nullSerializer;
if (base._internalSettings != null) {
@@ -582,9 +561,7 @@ public Class>[] getViews() {
public void serializeAsProperty(Object bean, JsonGenerator g, SerializationContext ctxt)
throws Exception
{
- // inlined 'get()'
- final Object value = (_accessorMethod == null) ? _field.get(bean)
- : _accessorMethod.invoke(bean, (Object[]) null);
+ final Object value = get(bean);
// Null handling is bit different, check that first
if (value == null) {
@@ -657,9 +634,7 @@ public void serializeAsOmittedProperty(Object bean, JsonGenerator g, Serializati
public void serializeAsElement(Object bean, JsonGenerator g, SerializationContext ctxt)
throws Exception
{
- // inlined 'get()'
- final Object value = (_accessorMethod == null) ? _field.get(bean)
- : _accessorMethod.invoke(bean, (Object[]) null);
+ final Object value = get(bean);
if (value == null) { // nulls need specialized handling
if (_nullSerializer != null) {
_nullSerializer.serialize(null, g, ctxt);
@@ -771,9 +746,12 @@ protected ValueSerializer