簡體   English   中英

如何在不得到編譯器警告的情況下重用泛型類

[英]How to reuse a generic class without getting a compiler warning

假設我有以下域模型,為說明起見,我對其進行了一些簡化。

public abstract class JsonSerializer<T> {

    public abstract JsonElement toJsonElement(final T object, final Locale locale);

    public JsonArray toJsonArray(final Collection<T> objects, final Locale locale) {
        return objects.stream().map(t -> toJsonElement(t, locale)).collect(JsonArray::new, JsonArray::add, JsonArray::addAll);
    }
}

public class FruitJsonSerializer<T extends Fruit> implements JsonSerializer<T> {}

public abstract class Fruit {}

public class Banana extends Fruit {}

public class Apple extends Fruit {}

然后,當我想序列化任何水果時,我會做:

FruitJsonSerializer serializer = new FruitJsonSerializer();
serializer.toJsonElement(new Banana());
serializer.toJsonElement(new Apple());

但是我從編譯器處收到一條警告,說它是原始類型成員對“ toJsonElement”的未經檢查的調用。

在每個實現中都沒有一個序列化程序聲明的情況下( FruitJsonSerializer<Apple>FruitJsonSerializer<Banana>等),如何避免出現此警告?

通用參數應該是具體的類,而不是類的子集。 您可以聲明JsonSerializer<Apple>JsonSerializer<Banana> 如果沒有參數,則將其視為JsonSerializer<Fruit>

如果您不想使FruitJsonSerializer通用,則不應編寫FruitJsonSerializer<T extends Fruit> if。 JsonSerializer<Fruit>繼承它就足夠了。 那是我的變體:

public static interface JsonSerializer<T> {
    JsonElement toJsonElement(final T object);
    JsonArray toJsonArray(final Collection<? extends T> objects, Locale locale);
}

public static class FruitJsonSerializer implements JsonSerializer<Fruit> {}

請注意,通配符用於Collection<? extends T>通用參數Collection<? extends T> Collection<? extends T>

您可以使用? 通配符

FruitJsonSerializer<? super Fruit> serializer = new FruitJsonSerializer<>();

編輯:更改為超級。

如果類A使用泛型

  • 類A可以使用基類或接口B處理多種不同的對象類型,
  • 您想將某些A實例的可用性限制為特定的B子類。

例如, List可以處理所有Object子類,並且List<String>通過編譯器類型檢查被限制為String元素,因此可以避免某些類型的細微錯誤。

您的JsonSerializer是調用泛型的有效示例。 但是我對FruitJsonSerializer表示懷疑。

我建議從FruitJsonSerializer中刪除類型參數:

public class FruitJsonSerializer implements JsonSerializer<Fruit> {}

您的示例暗示您計划對任何種類的水果使用完全相同的FruitJsonSerializer,因此似乎不需要FruitJsonSerializer <Apple>或任何其他專門技術。

也許我錯了,然后按原樣保留類定義,並以正確的方式構造實例:

FruitJsonSerializer<Fruit> generalSerializer = new FruitJsonSerializer<>();
FruitJsonSerializer<Apple> applesSerializer = new FruitJsonSerializer<>();

第一個可以用於任何Fruit ,第二個只能用於Apples

toJsonArray() :將toJsonArray()方法更改為:

JsonArray toJsonArray(final Collection<? extends T> objects, final Locale);

否則,您將無法將List<Apple>傳遞給JsonSerializer<Fruit>

暫無
暫無

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

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