Java @提供@Named donds';不适用于超类型声明的变量

Java @提供@Named donds';不适用于超类型声明的变量,java,guice,Java,Guice,我目前正在探索Guice功能,并面临一种奇怪的行为——当我将变量声明为 @Inject @Named("dragon") Dragon dragon2; 注入按预期工作,但当我想将dragon2声明为接口(它实现了生物)时,我。e 我犯了一个错误 没有绑定用@com.google.inject.name.Named(value=dragon)注释的warlock.rincewind.biods.biodle的实现 以下是我的提供者方法: @Named("dragon") @Provides p

我目前正在探索Guice功能,并面临一种奇怪的行为——当我将变量声明为

@Inject
@Named("dragon")
Dragon dragon2;
注入按预期工作,但当我想将dragon2声明为接口(它实现了生物)时,我。e

我犯了一个错误

没有绑定用
@com.google.inject.name.Named(value=dragon)
注释的warlock.rincewind.biods.biodle的实现

以下是我的提供者方法:

@Named("dragon")
@Provides
public Dragon providesDragon() {
    Dragon d = new Dragon("Morkeleb");
    return d;
}
我知道,有很多不同的方法可以克服这一点(最简单的一种是改变生物的返回类型),但我正试图找出这种限制的原因

例如,考虑:

interface Creature { }

class Dragon implements Creature { }
class Dog implements Creature { }

public class Kennel {
    @Inject @Named("foo") Creature c;
}

public class KennelModule extends Abstract Module {
    @Override
    protected void configure() {
        bind(Dragon.class).annotatedWith(Names.named("foo"));
        bind(Dog.class).annotatedWith(Names.named("foo"));
    }
}
您的注射剂如何知道是在这里绑定
还是

不可能注入关键帧不是协变的。您需要做的是,指定要注入的子类,并将其绑定到要注入的接口或超类。换句话说:

public class KennelModule extends Abstract Module {
    @Override
    protected void configure() {
        bind(Creature.class).annotatedWith(Names.named("foo").to(Dragon.class);
    }
}

这会给你想要的行为。当然,您还可以为
Dragon
绑定注入。

在Guice中,
Key
s不是协变的。因此,将
@命名(“龙”)生物
@命名(“龙”)龙
绑定到不同的实现或实例是完全可以接受的。
public class KennelModule extends Abstract Module {
    @Override
    protected void configure() {
        bind(Creature.class).annotatedWith(Names.named("foo").to(Dragon.class);
    }
}