Java 获取实现多个对象创建接口的参数

Java 获取实现多个对象创建接口的参数,java,interface,implementation,guice,Java,Interface,Implementation,Guice,我有一个我想用实现两个接口的对象创建的对象假设,我不能修改对象的类来创建第三个接口,它将扩展两个接口。使用guice创建此类对象的最佳方法是什么?在需要时注入一个接口并转换到另一个接口,或者将同一对象注入两个不同的接口 我知道这两种方法都很难看,但我认为整个方法都很难看。如果一个类实现两个不同的接口,那么对象模型中可能存在缺陷。如果一个类实现了两个不相交的接口,那么它有两个不同的方面,您可能应该改进它,因为Java确实允许您进行接口组合,即 static class TL<T extend

我有一个我想用实现两个接口的对象创建的对象假设,我不能修改对象的类来创建第三个接口,它将扩展两个接口。使用guice创建此类对象的最佳方法是什么?

在需要时注入一个接口并转换到另一个接口,或者将同一对象注入两个不同的接口


我知道这两种方法都很难看,但我认为整个方法都很难看。如果一个类实现两个不同的接口,那么对象模型中可能存在缺陷。如果一个类实现了两个不相交的接口,那么它有两个不同的方面,您可能应该改进它,因为Java确实允许您进行接口组合,即

static class TL<T extends IA & IB> extends TypeLiteral<T>(){}
但是您会注意到,必须有一个具体的类型T来实现这两个接口。Java不能为变量发明组合类型——类型必须与实际的类文件一起存在

我惊讶地发现,确实有可能做到这一点。我怀疑这是Guice的维护人员建议不要进入的黑暗角落,这可能不是一个好主意

有关以下代码的注意事项:

我实际上是在滥用Guice的内置保护措施,将IA上的TL子类TypeLiteral参数化,而不是T上的TypeLiteral参数化,这是正确的。所以事实上,整个例子可能是偶然的。 这没有多大帮助。在这种情况下,最终必须在某个地方指定类的具体类型。它允许您在使用对象的类中指定具体类型,但在绑定对象或直接从注入器请求对象时则不需要 几乎没有人能理解Java泛型的TypeA和TypeB语法——准备好让任何一个看到这段代码的人完全困惑,即使是一些Java大师 如果以后尝试使用只实现其中一个接口的对象,可以创建一个实现一个接口并委托给该对象的动态代理,但仍然需要创建一个结合了这两个接口的接口,以便为Java提供一个可引用的类型 公共X类{

static final class TL<T extends IA & IB> extends TypeLiteral<IA> {}

interface IA {}
interface IB {}
static final class Both implements IA, IB {}

@Test
public void test() {
    Injector inj = Guice.createInjector(new M());
    Both object = inj.getInstance(Key.get(new TypeLiteral<Both>(){}));
    assertNotNull(object);
    Foo<Both> foo = inj.getInstance(Key.get(new TypeLiteral<Foo<Both>>() {}));
    assertTrue (object instanceof IA);
    assertTrue (object instanceof IB);
    assertNotNull(foo);
    assertNotNull(foo.obj);
}

static class Foo<T extends IA & IB> {
    private final T obj;
    @Inject
    Foo(T obj) {
        this.obj = obj;
    }
}

static class M extends AbstractModule {
    @Override
    protected void configure() {
        bind(new TL<Both>()).to(Both.class);
    }
}
}
所以我认为答案是,你可以,但你可能不应该这样做。

为什么不这样做:

// Your original class
class AB implements IA, IB {...}

// In a Module
bind(AB.class).in(SOMESCOPE);
bind(IA.class).to(AB.class);
bind(IB.class).to(AB.class);

// In the object to be inejcted with AB
class MyClass {
    @Inject IA a;
    @Inject IB b;
}

最后,你会得到a==b,这不符合要求吗?

你想创建一个类的实例,该类使用guice实现两个接口?还是我误解了这个问题?@extraneon,是的。我想将这样的对象注入到我的类中。在此之前,我应该创建这样的对象。+1。可能你是对的。这不是生产proEject和我决定尝试一些不同的东西,可能走错了方向。有趣的解决方案。谢谢。我只是看到我的答案实际上映射到了Sean的答案,它只是显示了一些实际的代码。+1,但我不会使用它,因为我认为字段注入不应该在项目中使用,只应该在示例中使用。按照这个解决方案,最好当然,我在这里使用字段注入是为了展示一个小片段;主要思想是将IA和IB作为两个不同的实例注入,尽管它们是相同的。