我正在使用Google Guice开发依赖于注入的基于JAX-RS的Java应用程序。我的代码中包含以下界面:

public interface LockProvider<L extends Lock> {
    Optional<L> acquireLock(String lockId);

    void releaseLock(L lock);
}


在上面的界面中,Lock是一个定义如下的界面:

public interface Lock {
    String getLockId();
}


锁接口由以下类实现:

public class DynamoDBLock implements Lock {
    private final String lockId;
    private final LockItem underLyingLock;

    public DynamoDBLock(final String lockId, final LockItem underLyingLock) {
    this.lockId = lockId;
    this.underLyingLock = underLyingLock;
    }

    @Override
    public String getLockId() {
        return lockId;
    }

    public LockItem getUnderlyingLock() {
        return underlyingLock;
    }
}


LockProvider接口由以下类实现:

public class DynamoDBLockProvider implements LockProvider<DynamoDBLock> {
    Optional<DynamoDBLock> acquireLock(String lockId) {
        //implementation here
    }

    void releaseLock(DynamoDBLock lock) {
        LockItem underlyingLockItem = lock.getUnderlyingLockItem();
        //do something with underlyingLockItem
    }
}


我不希望LockProvider之外的应用程序中的类了解underLying锁定项,这就是为什么我没有在Lock接口中包含getUnderlyingLockItem的原因。

现在,当我尝试将LockProvider绑定到DynamoDBLockProvider时,如下所示:

bind(new TypeLiteral<LockProvider<Lock>>() {}).to(DynamoDBLockProvider.class);


我在Eclipse中收到以下编译错误:

类型为LinkedBindingBuilder >的to(Class >)方法不适用于参数(Class )


我了解DynamoDBLockProvider 不是LockProvider 的子类。是否可以完成我想做的事情,即将LockProvider绑定到DynamoDBLockProvider(以一种干净有效的方式)?

最佳答案

您的DynamoDBLockProvider实例不是LockProvider<Lock>的实例。但是它们是LockProvider<? extends Lock>的实例。

一个平行的例子是ArrayList<Integer>的实例不是List<Number>的实例,而是根据this questionList<? extends Number>实例。

将其应用于Guice,您将获得完全相同的编译失败。假设您有一个像这样的课程:

public class IntegerList extends ArrayList<Integer> {}


然后像这样绑定它是行不通的:

binder.bind(new TypeLiteral<List<Number>>() {}).to(IntegerList.class); //won't compile



  是否可以完成我想做的事情,即将LockProvider绑定到DynamoDBLockProvider(以一种干净有效的方式)?


以下绑定将起作用:

binder.bind(new TypeLiteral<LockProvider<? extends Lock>>() {}).to(DynamoDBLockProvider.class);

10-05 22:13