[英]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使用泛型
例如, 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.