找到与Java反射最匹配的writeMethod
Commons BeanUtils getMatchingAccessibleMethod查找匹配,但不是最佳匹配 考虑这个简单的例子:找到与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");
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的名称,有什么想法吗?