当前位置: 首页 > 知识库问答 >
问题:

guice:自动绑定泛型类

狄飞尘
2023-03-14

可以自动绑定泛型类吗?考虑一下:

通用接口:

public interface IAction<T> {
     T echo(T inst);
}

长子类型:

public class LongAction implements IAction<Long> {    
    @Override
    public Long echo(Long inst) {return inst;}
}

字符串子类型:

public class StringAction implements IAction<String> {
    @Override
    public String echo(String inst) {return inst;}
}

自定义模块:公共类CustomModule扩展AbstractModule{

@Override
protected void configure() {
  //do this automagically?
  bind(new TypeLiteral<IAction<String>>() {}).to(StringAction.class);
  bind(new TypeLiteral<IAction<Long>>() {}).to(LongAction.class);
  //
}

}

主要的

// i know i can obtain the correct instance
IAction<String> is = injector.getInstance(new Key<IAction<String>>(){});

是否可以以某种方式(例如:基抽象类、反射或其他)自动绑定StringAction和LongAction类的绑定?我试过使用反射,但没有用。


共有2个答案

云宝
2023-03-14

我设法欺骗了编译器。

class CustomModule extends AbstractModule {

static class Holder<T> {
    Class<T> param;
    Class<IAction<T>> klass;

    Holder(Class<?> p, Class<IAction<T>> k) {
        param = (Class<T>) p;
        klass = k;
    }
}

// this would be similar to the result of classpath scanning
List<IAction<?>> stuff;

public <T> void bindSome(Class<T> typeParameter, Class<IAction<T>> implementation) {
    Type parameterizedType = Types.newParameterizedType(IAction.class, typeParameter);
    bind((TypeLiteral<IAction<T>>) TypeLiteral.get(parameterizedType)).to(implementation);
}

public CustomModule() {
    stuff = new ArrayList<>();
    stuff.add(new StringAction());
    stuff.add(new LongAction());
}

@Override
protected void configure() {
    for (IAction<?> act : stuff) {
        System.out.printf("Configuring %s for %s\n", act.getTypeArguments(), act.getClass());
        //the following doesn't work because the compiler cannot understand that 
        //the 1st argument T is the same T in 2nd argument Class<T>
        //bindSome(act.getTypeArguments(), act.getClass());

        //w00t? compiler is tricked?? <String> is erased, but the holder preserves proper class?
        Holder<String> holder = new Holder(act.getTypeArguments(), (Class<IAction<String>>) act.getClass());
        bindSome(holder.param, holder.klass);

        //this is what I want to avoid doing manually
        //bind(new TypeLiteral<IAction<String>>() {}).to(StringAction.class);
    }
}
}
马弘和
2023-03-14

如果不想显式列出实现,则必须进行某种类路径扫描。例如,Guava的ClassPath类提供了一些支持。

请注意,类路径扫描与Guice的设计理念有些背道而驰。为您编写的每个实现向模块添加一行代码真的需要这么多额外的努力吗?

 类似资料:
  • 问题内容: 以下代码在t3行中出现编译错误: 错误消息是: 类型不匹配:无法从对象转换为T 我知道我可以使用强制转换或手动绑定来解决问题,我的问题是: 编译器进行自动绑定是否如此困难,是否会失败? 编辑:添加了错误消息。 编辑:添加了另一个示例如何不会发生该错误。 编辑:删除了第二个示例,因为它令人困惑,使问题更加清楚。 问题答案: 在第一种情况下,您有两个具有名为的类型参数的泛型方法,但是这些类

  • 使用Guice 3.0,我尝试注入一个提供程序,该提供程序可以抛出特定的已检查异常。所以我使用了抛出提供者扩展。 我为提供者创建了一个接口: 及其实施: 我在要注入提供者的对象上使用@Inject注释: 现在,我的问题是:如何绑定这个提供者? 由于使用了泛型,我想到了使用TypeLiteral: 但是对于这个bind()方法来说,

  • 我最近开始使用Google Guice,通过我在网络上找到的教程和代码工作,但现在我被困住了。 我已经尝试创建了一个,我可以在每个实体DAO的基础上扩展该。我很难弄清楚如何配置一个现有的私有Guice模块。 这里是我的,其中是一个使用作为标识的实体。类是另一个不依赖于的实体(目前,我正在尝试让它一开始就简单)。 当尝试运行以下内容时,我会得到: Google Guice用户指南在这里没有真正帮助我

  • 我正在开发一个基于JAX-RS的Java应用程序,使用Google Guice进行依赖注入。我的代码中有以下接口: 在上面的接口中,Lock是一个定义如下的接口: 锁接口由以下类实现: LockProvider接口由以下类实现: 除了LockProvider之外,我不希望应用程序中的类知道底层锁项,这就是为什么我没有在lock接口中包含getUnderlyingLockItem。 现在,当我尝试将

  • 我正在尝试用Guice注入泛型类型。我有存储库 所以当我创建光标时

  • 主要内容:1 泛型数据绑定的示例在简单的数据绑定中,我们使用了Map类,该类使用String作为键,使用Object作为值对象。取而代之的是,我们可以换成一个具体类型的Java对象,然后将其类型转换为JSON。 1 泛型数据绑定的示例 1.1 编写核心类 MainApp: 1.2 运行测试