使用方法重载来最具体地描述Java Class.cast

时间:2018-08-01 18:20:23

标签: java

我有一个看起来像这样的代码

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

我的最终目标是执行与传递的对象最接近的功能。

3 个答案:

答案 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;如果在参数类型没有(或可能没有)根本不同的情况下进行方法重载,那么最好不要重载并使用不同的方法名称。