@@ -32,7 +32,7 @@ public Property[] apply(Class<?> type) {
3232
3333 Map <String , Method > getters = new HashMap <>();
3434 Map <String , Method > isGetters = new HashMap <>();
35- Map <String , Method > setters = new HashMap <>();
35+ Map <String , List < Method > > setters = new HashMap <>();
3636 for (Method i : methods ) {
3737 if (i .getName ().startsWith ("get" ) && i .getName ().length () > 3 && i .getParameterCount () == 0
3838 && i .getReturnType () != void .class ) {
@@ -49,7 +49,7 @@ public Property[] apply(Class<?> type) {
4949 isGetters .put (name , i );
5050 } else if (i .getName ().startsWith ("set" ) && i .getName ().length () > 3 && i .getParameterCount () == 1 ) {
5151 String name = Character .toLowerCase (i .getName ().charAt (3 )) + i .getName ().substring (4 );
52- setters .put (name , i );
52+ setters .computeIfAbsent (name , k -> new ArrayList <>()). add ( i );
5353 }
5454 }
5555
@@ -62,7 +62,7 @@ public Property[] apply(Class<?> type) {
6262 if (get == null ) {
6363 get = isGetters .get (i ); // If there is no "get" getter, use the "is" getter
6464 }
65- Method set = setters .get (i );
65+ Method set = selectBestSetter ( get , setters .get (i ) );
6666 if (get == null ) {
6767 ret .add (new Property (i , get , set , set .getParameterTypes ()[0 ]));
6868 } else if (set == null ) {
@@ -84,6 +84,31 @@ public Property[] apply(Class<?> type) {
8484 }
8585 };
8686
87+ private static Method selectBestSetter (Method getter , List <Method > candidates ) {
88+ if (candidates == null || candidates .isEmpty ()) {
89+ return null ;
90+ }
91+ if (candidates .size () == 1 || getter == null ) {
92+ return candidates .get (0 );
93+ }
94+ Class <?> getterType = getter .getReturnType ();
95+ // prefer exact match
96+ for (Method m : candidates ) {
97+ if (m .getParameterTypes ()[0 ] == getterType ) {
98+ return m ;
99+ }
100+ }
101+ // then prefer assignable match
102+ for (Method m : candidates ) {
103+ Class <?> setterType = m .getParameterTypes ()[0 ];
104+ if (getterType .isAssignableFrom (setterType ) || setterType .isAssignableFrom (getterType )) {
105+ return m ;
106+ }
107+ }
108+ // fallback to first
109+ return candidates .get (0 );
110+ }
111+
87112 public static Property [] getPropertyDescriptors (Object param ) {
88113 return CACHE .computeIfAbsent (param .getClass (), FUNCTION );
89114 }
0 commit comments