给定
private someMethod(String value) {
// do string things
}
private someMethod(Integer value) {
// do number things
}
根据clazz
的类型和input
的值,下面的代码是否可以调用正确的someMethod
?
public <T> void doSomething(T input, Class<T> clazz) {
// Cast the input to the type specified by clazz
// Call a method that expects a parameter of the type specified by clazz
someMethod(clazz.cast(input));
}
如果不能这样做,那么最好的方法是什么,而不用对静态类型常量进行长时间的if/else硬检查?
3条答案
按热度按时间qlzsbp2j1#
第一个(快速)“解决方案”
实际上,没有Java内置的机制来为您处理这种调度,这意味着您必须自己完成。
但是...为了避免更长的if-else链,您可以使用一个Map,将类型Map到您想要调用的消费方法。
现在您可以执行以下操作:
构建调度Map时要小心,任何错误都会导致调用
doSomething
方法时出现运行时错误,甚至会出现编译器警告。不是很完美,但也许是一条路要走...
进一步考虑
这个手动调度对你来说是一个很好的提示,可能会有更多像OOP的解决方案。通常,在你的思想后面潜伏着一个 * 类型 *...
因此,首先为该类型创建一个接口:
注意,泛型类型在这里也被删除了,现在你可以为它创建一些类了:
有了这些准备,您就可以简化您的公共方法:
使用它就像这样简单:
这种方法的主要优点是......扩展它仅仅意味着添加另一个具体的类。不需要更改其他任何内容。
nafvub8i2#
在运行时,Java只根据调用方法的对象动态地分派方法,即从被调用者的Angular 来看
this
,也就是“receiver parameter”,或者你在调用中调用的这一部分:运行时选择哪种方法完全取决于该部分。如果
foo
在运行时存储Dog
的示例,则调用Dog.eat
。如果它存储Cat
的示例,则调用Cat.eat
。但是,这里要做的似乎是基于
food
在运行时存储的类型进行动态调度,因为Java没有这样做,所以要么使用if-else-if链手动调度,要么更改调用,使food
成为接收方:因为在您的例子中参数是
String
和Integer
,所以您需要为它们编写 Package 器类,以便能够向它们添加方法。现在
doSomething
只需要取一个SomeMethodInput
:您可能会注意到这与visitor模式之间的一些相似之处,您是对的-这正是visitor模式实现
this
和参数双重调度的方式。我在这里展示的还不是这样,因为它只对参数进行调度。ogq8wdun3#
您可以使用反射API来实现这一点。