在没有双重分派/访问者模式的情况下解决 Java 的静态方法分派
我正在使用提供以下方法的类 Foo
:
String overloadedMethod(Object)
String overloadedMethod(Goo)
由于 Java 在非接收者参数上静态分派,我不能只传递我的 value
(这是一个 Object
,但可能具有动态类型 Goo
)并依赖 JVM 动态选择“正确”的方法。
这是我当前(丑陋的)解决方法:
Object value = ...;
Foo foo = new Foo();
if (value instanceof Goo) {
Goo gooValue = (Goo) value;
return foo.overloadedMethod(gooValue); // -> overloadedMethod(Goo)
} else {
return foo.overloadedMethod(value); // -> overloadedMethod(Object)
}
是否有更好的方法可以在不修改 Foo
中的代码(包含重载方法的类)的情况下执行此操作?
I am using a class Foo
that provides these methods:
String overloadedMethod(Object)
String overloadedMethod(Goo)
Since Java statically dispatches on the non-receiver argument, I cannot just pass my value
(which is an Object
, but might have dynamic type Goo
) and rely on the JVM to dynamically choose the "correct" method.
This is my current (ugly) work-around:
Object value = ...;
Foo foo = new Foo();
if (value instanceof Goo) {
Goo gooValue = (Goo) value;
return foo.overloadedMethod(gooValue); // -> overloadedMethod(Goo)
} else {
return foo.overloadedMethod(value); // -> overloadedMethod(Object)
}
Is there a better way of doing this without modifying the code in Foo
(the class containing the overloaded method)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当然,您始终可以使用反射来查找适用的方法的最具体版本,但这可能很快就会变得很麻烦。
但是,如果这两个调用导致完全不同的行为,那么 Foo 要么被设计用于访问者模式(即双重调度),要么被破坏。
Of course you could always use reflection to find the most specific version of the method that applies, but that could get hairy real quick.
But if those two calls result in entirely different behaviour, then Foo is either designed to be used in a visitor pattern (i.e. with double dispatch) or it is broken.
您可以查看Java 多方法框架。 它几乎是围绕您所提议的内容的一层,但至少它被抽象为一个不属于您的责任的逻辑模块?
(据我所知,没有干净的方法可以在不诉诸反射/黑客实例的情况下做到这一点)
You could take a look at the Java MultiMethod Framework. It's pretty much a layer around what you're proposing, but atleast it's abstracted into a logical module that's not your responsibility?
(As far as I'm aware, there's no clean way to do this without resorting to reflection/instanceof hacking)