簡體   English   中英

通用接口和實現 - 類型無法轉換

[英]Generic interface and implementation - type cannot be converted

我有一個通用接口定義為:

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

我從這個問題中了解到了? 通配符不能完全相同所以我的問題是 - 我能做我想做的事 - 使用界面嗎? 如果是這樣,怎么樣? 或者我接近這個錯誤?

我已經問過兩個與之相關的問題,這些問題一直有所幫助( 第一第二

我沒有看到以下不適合您的原因:

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());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM