找到与Java反射最匹配的writeMethod

找到与Java反射最匹配的writeMethod,java,reflection,Java,Reflection,Commons BeanUtils getMatchingAccessibleMethod查找匹配,但不是最佳匹配 考虑这个简单的例子: public class TestReflection extends TestCase { public static class BeanA { private DataX data; public BeanA setData(DataX x) { System.out.println("setData x");

Commons BeanUtils getMatchingAccessibleMethod查找匹配,但不是最佳匹配

考虑这个简单的例子:

public class TestReflection extends TestCase {

  public static class BeanA {
    private DataX data;
    public BeanA setData(DataX x) {
      System.out.println("setData x");
      return this;
    }
    public BeanA setData(DataY y) {
      System.out.println("setData y");
      return this;
    }
  }

  static class DataX {
  }
  static class DataY extends DataX {
  }
  static class DataZ extends DataY {
  }

  public void testPropertyUtils() {
    try {
      BeanA a = new BeanA();
      System.out.println("--- setters:");
      a.setData(new DataX());
      a.setData(new DataY());
      a.setData(new DataZ());
      System.out.println("--- invokeMethod");
      MethodUtils.invokeMethod(a, "setData", new DataZ());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
(提示:invokeMethod使用getMatchingAccessibleMethod)

上述代码输出

--- setters:
setData x
setData y
setData y
--- invokeMethod
setData x
最后一行应该是“setData y”,因为用DataZ对象调用“setData”的最佳匹配应该是接口中带有DataY的对象(就像setData(new DataZ())一样)


有没有找到最佳匹配的方法,或者我必须自己编写代码?

我只是想知道MethodUtils.java中它是如何工作的,所以我查看了里面的内容。为了确定哪种方法应被用作最佳匹配,每种方法都将获得成本。要计算成本,有一种方法(有一些额外的dbg输出):

所以输出是

--- setters:
setData x
setData y
setData y
--- invokeMethod
----------- start calculate cost from class Lolka$DataZ to class Lolka$DataX------------
class Lolka$DataZ and class Lolka$DataX are  not equal
class Lolka$DataZ and class java.lang.Object are  not equal
COST IS 3.5
----------- start calculate cost from class Lolka$DataZ to class Lolka$DataY------------
class Lolka$DataZ and class Lolka$DataY are  not equal
class Lolka$DataZ and class Lolka$DataX are  not equal
class Lolka$DataZ and class java.lang.Object are  not equal
COST IS 4.5
setData x
--- setters:
setData x
setData y
setData y
--- invokeMethod
setData y
所以invokeMethode假设转换DataX只是一个继承级别的表单对象,而DataY是2。所以DataX方法“更便宜”。这就是背后的逻辑

UPD: 将dest更改为src效果很好,因此如果我使用

private static float getObjectTransformationCost(Class srcClass, Class destClass) {
    float cost = 0.0f;
    while (srcClass != null && !destClass.equals(srcClass)) {
        if (destClass.isInterface() && isAssignmentCompatible(destClass,srcClass)) {
            cost += 0.25f;
            break;
        }
        cost++;

        srcClass = srcClass.getSuperclass();
    }

    if (srcClass == null) {
        cost += 1.5f;
    }

    return cost;
}
输出是

--- setters:
setData x
setData y
setData y
--- invokeMethod
----------- start calculate cost from class Lolka$DataZ to class Lolka$DataX------------
class Lolka$DataZ and class Lolka$DataX are  not equal
class Lolka$DataZ and class java.lang.Object are  not equal
COST IS 3.5
----------- start calculate cost from class Lolka$DataZ to class Lolka$DataY------------
class Lolka$DataZ and class Lolka$DataY are  not equal
class Lolka$DataZ and class Lolka$DataX are  not equal
class Lolka$DataZ and class java.lang.Object are  not equal
COST IS 4.5
setData x
--- setters:
setData x
setData y
setData y
--- invokeMethod
setData y

此外,当setter出于方法链接的目的“返回this”时,反射不能用于查找writeMethod的名称,因为java反射总是希望返回类型void与(我认为已经过时的)bean规范匹配。关于如何获取invokeMethod调用的writeMethod的名称,有什么想法吗?