为了避免在运行时缺少Java泛型,将超类型绑定到子类实例

为了避免在运行时缺少Java泛型,将超类型绑定到子类实例,java,generics,binding,Java,Generics,Binding,想象一种方法,例如 public <F extends Fruit> Juice<F> makeJuiceFrom(Collection<F> fruits) { for (F fruit: fruits) { handleFruit(fruit); } return ... } 橘子和苹果延伸出果实 然而,现在我当然被迫为硬代码绑定修改一个方法: private void HandleFruit(Fruit frui

想象一种方法,例如

public <F extends Fruit> Juice<F> makeJuiceFrom(Collection<F> fruits) {
    for (F fruit: fruits) {
        handleFruit(fruit);
    }
    return ...
}
橘子和苹果延伸出果实

然而,现在我当然被迫为硬代码绑定修改一个方法:

private void HandleFruit(Fruit fruit) {
if (Fruit instanceof Apple)
 handleFruit(((Apple)fruit));
else if (...)
。。。 }

是否有任何方法可以动态绑定它:

private void handleFruit(Fruit fruit) {
    handleFruit(((fruit.getType)fruit));
}

我建议您将该方法添加到
Fruit
,并这样调用它

interface Fruit {
    handleFruit();
}

public <F extends Fruit> Juice<F> makeJuiceFrom(Collection<F> fruits) {
    for (Fruit fruit: fruits) {
        fruit.handleFruit();
    }
    return ...
}
接口水果{
handleFruit();
}
公共果汁MakeJuice From(收集水果){
用于(水果:水果){
水果;
}
返回。。。
}

是的,您正在查找

Fruit
的每个子类中编写一个方法:

public void visit(Juice j) {
    j.handleFruit(this);
}
现在,您可以拥有不同类型的
handleFruit()
,并且根据
visit()
方法的实现类,
this
的静态类型是特定的(
Apple
/
Orange
/…),并且将调用正确的方法


使用
fruit调用。从
Juice
类访问(this)

将其作为
fruit
类的方法并使用多态性如何?参数在编译时解析,因此在Java中无法实现。要么照@kraskevich说的做,要么使用访问者模式。请注意,您要查找的关键字是multiple dispatch。Wikipedia等有很多关于它的页面,以及它与Java的关系。@kraskevich只有在只有一个
JuiceMaker
实现的情况下才可行,所以您不需要在这方面动态调度。否则,这是双重分派,需要臭名昭著的冗长复杂的访问者模式。但是,假设
handleFruit()
依赖于
JuiceMaker
(毕竟,它当前在该类中),那么只有当
JuiceMaker
是单个实现时,它才会工作。
public void visit(Juice j) {
    j.handleFruit(this);
}