我有一个通用接口定义为:
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) {
}
}
以下是上面引用的四个类的定义:
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
实现,因此可以在需要时将其换出,
ItemService<? extends Slicer, ? extends ItemSlice> itemService = new DynamoDbItemService itemService();
但是如果我尝试像这样使用itemService
:
ItemSlice slice = itemService.getItemHistory(itemId, DynamoDbSlicer.first(1));
slice = itemService.getItemHistory(itemId, slice.next());
我收到这两个编译错误:
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
我从this question得知?
通配符不能相同,所以我的问题是-我可以做我想做的事情-使用该接口吗?如果是这样,怎么办?还是我处理方法不正确?
答案 0 :(得分:1)
我看不出以下原因对您不起作用的原因:
ItemService<DynamoDbSlicer, DynamoDbItemSlice> itemService = new DynamoDbItemService();
ItemSlice slice = itemService.getItemHistory("", new DynamoDbSlicer());
但是,如果您想使代码尽可能模块化,则可以使用此方法执行未经检查的强制转换(有些说法是纯邪恶的话)并获得所需的结果:
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());
}
然后当然有解决方案,将类型推断责任传递给存储值的实际字段。我本人会选择此解决方案,因为我认为它提供了最大的灵活性:
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());