我有一个看起来像这样的代码
function a(Object m) {}
function a(BasicDbObject) {}
function a(TypeA) {}
function a(TypeB) {}
function a(TypeC) {}
.....
function b(Object m) {
// Some function using Java reflection to determine class of Object m
Class X = c(m);
a(X.cast(m));
}
这是问题所在。即使是a(Object m)
,它始终执行a(BasicDbObject m)
而不是BasicDbObject
。
我的最终目标是执行与传递的对象最接近的功能。
答案 0 :(得分:4)
您尝试的操作无法完成,因为Java是静态类型的,并且方法重载是在编译时而不是运行时解决的。
解决运行时重载的唯一方法是使方法调用本身通过反射完成。
答案 1 :(得分:2)
严重的非回答:错误的方法。
您无需使用 reflection 动态确定类型,即可确定要调用的重载方法。
请使用多态。含义:不要过载,而是覆盖。
最放心:很难“反射” 工作。使其正确,健壮和稳定是一项极富挑战性的艰巨战斗。
您基本上想发明自己的个人动态调度实现。除非您有超级紧迫的理由这样做,否则这是一个糟糕的主意。因为您很可能会弄错它。很多很多次。甚至在您的代码正常工作时,稍后在生产中发生不可预见的事情时也会发生许多事件。
如前所述:不要这样做。不要与语言打架,而应使用语言为您提供的解决此类问题的手段:类的继承树和多态方法。然后让JVM决定要调用的方法。与您想出的相比,JVM最有可能做得更好。
答案 2 :(得分:1)
function a(Object m){}
函数a(BasicDbObject){}
当方法被重载时,可能不直观地知道要为任何参数集调用的方法,因为与覆盖方法的情况不同,该方法被调用的重载是在编译时(即静态)而不是在运行时(即动态)确定的。这种行为令人困惑,因为重写方法更为常见,这为我们设定了方法调用的期望。
有一些规则可以使鲁棒且尽可能简单地进行方法重载。这些在《有效的Java》(J。Bloch,第二版和第三版)中都得到了很好的枚举。
您的情况变得复杂,因为:
出现这种情况时,应尝试通过给重载使用不同的名称来纠正它。应该始终可以这样做,并且这样做通常可以提高代码的清晰度和可维护性。
如果由于某种原因无法做到这一点,那么最好的解决方法是将重载替换为一种方法,该方法接受最通用的参数类型,并根据传递的参数的最特定类型调用帮助程序方法。 / p>
因此,除了上述内容,您还可以通过使用...获得所需的行为。
public Function a(Object m) {
if (m instanceof BasicDbObject) return doDbObject(m);
if (m instanceof OtherDbObject) return doOtherDbObject(m);
return doGenericObject(m);
}
请注意,这不是Java在语言中采用模式匹配时要使用的代码。还请注意,此代码的作用是为重载赋予不同的名称,但是对独立方法的选择是在运行时使用instanceof
比较,而不是在编译时仅通过使用独立名称进行选择。
TLDR;如果在参数类型没有(或可能没有)根本不同的情况下进行方法重载,那么最好不要重载并使用不同的方法名称。