1515package com .google .api .client .util ;
1616
1717import java .lang .reflect .Field ;
18+ import java .lang .reflect .InvocationTargetException ;
19+ import java .lang .reflect .Method ;
1820import java .lang .reflect .Modifier ;
1921import java .lang .reflect .Type ;
22+ import java .util .ArrayList ;
23+ import java .util .List ;
2024import java .util .Map ;
2125import java .util .WeakHashMap ;
2226
@@ -112,6 +116,9 @@ public static FieldInfo of(Field field) {
112116 /** Field. */
113117 private final Field field ;
114118
119+ /** Setters Method for field */
120+ private final Method []setters ;
121+
115122 /**
116123 * Data key name associated with the field for a non-enum-constant with a {@link Key} annotation,
117124 * or data key value associated with the enum constant with a {@link Value} annotation or {@code
@@ -127,6 +134,21 @@ public static FieldInfo of(Field field) {
127134 this .field = field ;
128135 this .name = name == null ? null : name .intern ();
129136 isPrimitive = Data .isPrimitive (getType ());
137+ this .setters = settersMethodForField (field );
138+ }
139+
140+ /**
141+ * Creates list of setter methods for a field only in declaring class.
142+ */
143+ private Method [] settersMethodForField (Field field ) {
144+ List <Method > methods = new ArrayList <Method >();
145+ for (Method method : field .getDeclaringClass ().getDeclaredMethods ()) {
146+ if (method .getName ().toLowerCase ().equals ("set" + field .getName ().toLowerCase ())
147+ && method .getParameterTypes ().length == 1 ) {
148+ methods .add (method );
149+ }
150+ }
151+ return methods .toArray (new Method [methods .size ()]);
130152 }
131153
132154 /**
@@ -203,6 +225,20 @@ public Object getValue(Object obj) {
203225 * If the field is final, it checks that value being set is identical to the existing value.
204226 */
205227 public void setValue (Object obj , Object value ) {
228+ if (setters .length > 0 ) {
229+ for (Method method : setters ) {
230+ if (value == null || method .getParameterTypes ()[0 ].isAssignableFrom (value .getClass ())) {
231+ try {
232+ method .invoke (obj , value );
233+ return ;
234+ } catch (IllegalAccessException e ) {
235+ // try to set field directly
236+ } catch (InvocationTargetException e ) {
237+ // try to set field directly
238+ }
239+ }
240+ }
241+ }
206242 setFieldValue (field , obj , value );
207243 }
208244
0 commit comments