通用接口和实现-类型无法转换 [英] Generic interface and implementation - type cannot be converted

查看:183
本文介绍了通用接口和实现-类型无法转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个通用接口定义为:

I have a generic interface defined as:

public interface ItemService<T extends Slicer, E extends ItemSlice> {
    E getItemHistory(final String id, final T slicer);
}

和一个实现:

public class DynamoDbItemService implements ItemService<DynamoDbSlicer, DynamoDbItemSlice> {
    public DynamoDbItemSlice getItemHistory(final String id, final DynamoDbSlicer slicer) {
    }
}

以下是上面引用的四个类的定义:

Here are the definitions of the four classes referenced above:

public interface Slicer {
    Map<String, ? extends Serializable> pointer();
}

public class DynamoDbSlicer implements Slicer {
    public Map<String, AttributeValue> pointer() {
    }
}

public interface ItemSlice extends Slice<Item> {
}

public interface Slice<T> {
    List<T> data();
    Slicer next();
}

public class DynamoDbItemSlice implements ItemSlice {
    publi ImmutableList<Item> data() {}
    public DynamoDbSlicer next() {}
}

我想引用ItemService接口,但要将其绑定到DynamoDbItemService实现,因此我可以根据需要将其交换出来,

I would like to reference the ItemService interface but for it to be bound to the DynamoDbItemService implementation so I can swap it out if necessary which I can do like so:

ItemService<? extends Slicer, ? extends ItemSlice> itemService = new DynamoDbItemService itemService();

但是如果我尝试像这样使用itemService:

but if I try to use itemService like this:

ItemSlice slice = itemService.getItemHistory(itemId, DynamoDbSlicer.first(1));
slice = itemService.getItemHistory(itemId, slice.next());

我遇到了这两个编译错误:

I get these two compilation errors:

Error:(231, 82) java: incompatible types: item.pagination.DynamoDbSlicer cannot be converted to capture#1 of ? extends pagination.Slicer

Error:(238, 62) java: incompatible types: pagination.Slicer cannot be converted to capture#2 of ? extends pagination.Slicer

我从这个问题中了解到?通配符不能相同,所以我的问题是-我可以做我想做的事情-使用该接口吗?如果是这样,怎么办?还是我处理方法不正确?

I understand from this question that ? wildcards cannot be identical so my question is - can I do what I want - work with the interface? If so, how? Or am I approaching this incorrectly?

我之前曾问过两个与此相关的问题,这些问题在整个过程中都有帮助(第二)

I have asked two previous questions related to this which have helped along the way (first and second)

推荐答案

我看不出以下内容对您不起作用的原因:

I don't see a reason why the following wouldn't work for you:

ItemService<DynamoDbSlicer, DynamoDbItemSlice> itemService = new DynamoDbItemService();
ItemSlice slice = itemService.getItemHistory("",  new DynamoDbSlicer());

但是,如果您想使代码尽可能模块化,则可以使用此方法执行未经检查的强制转换(有些说法是纯罪恶的)并获得所需的结果:

But if you would like to make the code as modular as possible you can use this method to perform an unchecked cast (pure evil some say) and get the result you want:

public static void main(String[] args) {

    ItemSlice slice = getMySlice(new DynamoDbItemService());
}

@SuppressWarnings("unchecked")
public static <T extends Slicer, E extends ItemSlice> E getMySlice(ItemService<T, E> service) {
    return service.getItemHistory("", (T) new DynamoDbSlicer());
}

然后当然是将类型推断责任传递给存储值的实际字段的解决方案.我本人会选择此解决方案,因为我认为它提供了最大的灵活性:

And then of course there is the solution of passing the type inference responsibility to the actual field that is storing the value. I myself would go for this solution, as I think it offers the most flexibility:

public class DynamoDbItemService<T extends Slicer, E extends ItemSlice> implements ItemService<T, E>

ItemService<DynamoDbSlicer, DynamoDbItemSlice> itemService = new DynamoDbItemService();
ItemSlice slice = itemService.getItemHistory("", new DynamoDbSlicer());

这篇关于通用接口和实现-类型无法转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆