On Thu, 6 Feb 2025 14:13:50 GMT, Roman Marchenko <rmarche...@openjdk.org> wrote:
>> Fixed `com.sun.beans.introspect.MethodInfo#MethodOrder` to make >> `Introspector.addMethod()` working properly when filtering methods out. >> >> Also fixed the test, and added the approptiate test case. > > Roman Marchenko has updated the pull request incrementally with one > additional commit since the last revision: > > Update test/jdk/java/beans/Introspector/DefaultMethodBeanPropertyTest.java > > Co-authored-by: Aleksandr Zvegintsev > <77687766+azveg...@users.noreply.github.com> > It was implemented in a way to minimize the difference between different > 'stopClasses' for the same object. In the example above, the next call will > produce the same properties: > ... > Thus, the methods of the current class have some priority over those of the > parent class. > But if the same class has multiple setFoo(xxx) methods, the behavior will be > undefined/unspecified. Currently, I see from `PropertyInfo` implementation that methods are just sorted by argument's type name if arguments are not assignable from each other. So, in case `Long` vs `Number`, `Long` will be chosen (`isAssignable()` check works); in case `Float` vs `Integer`, `Float` will be chosen (sorted by type name). I'm still wondering if there's any specification (tests?) describing this. At the time it looks like the current implementation is the only doc. If no docs, could you review the test cases below, please? Is it correct, or redundant, or incomplete? I will add them to the test when OK. Case 1: public interface A { default public void setParentFoo(Integer num) { } default public void setFoo(Integer num) { } } public class D implements A { public void setFoo(Number num) { } public void setLocalFoo(Long num) { } public void setLocalFoo(Float num) { } } Expecting: --- properties public void Test$D.setFoo(java.lang.Number) public void Test$D.setLocalFoo(java.lang.Float) public default void Test$A.setParentFoo(java.lang.Integer) --- methods public void Test$D.setFoo(java.lang.Number) public void Test$D.setLocalFoo(java.lang.Float) public default void Test$A.setFoo(java.lang.Integer) public void Test$D.setLocalFoo(java.lang.Long) public default void Test$A.setParentFoo(java.lang.Integer) Case 2: public class AC { public void setParentFoo(Integer num) { } public void setFoo(Integer num) { } } public class DC extends AC { public void setFoo(Number num) { } public void setLocalFoo(Long num) { } public void setLocalFoo(Float num) { } } Expecting: --- properties public void Test$DC.setFoo(java.lang.Number) public void Test$DC.setLocalFoo(java.lang.Float) public void Test$AC.setParentFoo(java.lang.Integer) --- methods public void Test$DC.setFoo(java.lang.Number) public void Test$DC.setLocalFoo(java.lang.Float) public void Test$AC.setFoo(java.lang.Integer) public void Test$DC.setLocalFoo(java.lang.Long) public void Test$AC.setParentFoo(java.lang.Integer) Case 3: interface Parent1<T> { T getValue(); } interface Parent2 { Runnable getValue(); } interface Parent3 extends Parent2, Parent1<Object> { Runnable getValue(); } abstract class Child implements Parent3 { public void setValue(Runnable value) { } } Expecting: --- properties public void Test$Child.setValue(java.lang.Runnable) --- methods public void Test$Child.setValue(java.lang.Runnable) ------------- PR Comment: https://git.openjdk.org/jdk/pull/23443#issuecomment-2656664421