[英]How to avoid unchecked cast when generic variable is resolved at runtime?
我有一個參數化值,在運行時解決:
public class GenericsMain {
public static void main(String... args) {
final String tag = "INT";
Field field = resolve(tag);
if (tag.equals("INT")) {
/*
In here I am using the "secret knowledge" that if tag equals INT, then
field could be casted to Field<Integer>. But at the same time I see an unchecked cast
warning at here.
Is there a way to refactor the code to be warning-free?
*/
Field<Integer> integerField = (Field<Integer>) field;
foo(integerField);
}
}
public static Field resolve(String tag) {
switch (tag) {
case "INT":
return new Field<>(1);
case "DOUBLE":
return new Field<>(1.0d);
default:
return null;
}
}
public static <T> void foo(Field<T> param) {
System.out.println(param.value);
}
static class Field<T> {
public final T value;
public Field(T value) {
this.value = value;
}
}
}
有沒有辦法在上面的代碼中避免未經檢查的強制轉換(標有長注釋)?
通常,沒辦法,因為類型參數綁定到聲明 。 您要做的是根據運行時值更改靜態聲明。
但是,您可以通過聲明添加類型參數的參數化方法來最小化未選中的強制轉換區域
@SuppressWarnings("unchecked")
private static <T> Field<T> asParameterized(Field<?> field) {
return (Field<T>) field;
}
然后使用
Field<Integer> intField = GenericsMain.<Integer> asParameterized(field);
您可以使用注釋來執行此操作。 使用以下注釋:
@SuppressWarnings("unchecked")
也許。 您可以使用對類型信息進行編碼的類型,而不是啞字符串標記。 請參閱此博客文章: http : //blog.pdark.de/2010/05/28/type-safe-object-map/
public class FieldKey<T> {
private String name;
public FieldKey(String name) {
this.name = name;
}
public String name() {
return name;
}
}
加上將Field
的構造函數更改為public Field(FieldKey<T> key, T value)
。
您仍然必須進行轉換,但編譯時間檢查將確保它們永遠不會失敗。
所有的答案都很好,但我認為沒有足夠強調為什么你會收到警告並且正在投擲。
您通過執行未經檢查的強制轉換明確規避了類型系統。 通過說“我有關於此類型的信息,編譯器無法使用” - 您告訴編譯器您更了解。
這當然是一個可行的和合理的使用案例:否則,這些類型轉換將不會被允許的,但一個警告是好的,因為它表明你應該是真的確定是什么類型。
這很有道理 。 事實上,如果您檢查像GSON這樣的序列化庫,那么它們就會充滿了這些警告和壓抑 。
不要擔心你的代碼 - 一切都很好。 如果有一種方法可以“欺騙”編譯器不發出本來會出現嚴重問題的警告:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.