[英]Type Safety warning when casting to generic class in Java
我有一堂課
class Property<T> {
value T;
public void setValue(T value) {
this.value = value;
}
}
現在,我有了一個列表List<Property<?>> properties
其中包含各種類型的各種屬性。 我遍歷此列表,並希望設置每個屬性的值。 因此,我需要將通用屬性轉換為正確的類型,例如:對於Integer:
if (property.getType().equals("Integer")) {
Property<Integer> propInt = (Property<Integer>) property;
propInt.setValue((Integer) values[i++]);
}
其中values[]
是一個對象數組,其中包含我要設置的值。
一切正常,但是Java抱怨類型安全“未經檢查從Property<?>
到Property<Integer>
”。 像這樣的支票
if (property instanceof Property<Integer>){...}
雖然不可能。 我該如何更改代碼以消除此警告,或者您知道我的案例的更好做法?
編譯器抱怨是因為property
的類型為Property<?>
,通常它可能是也不可能是Property<Integer>
類型。 由於類型擦除,這是當前Java語言的固有限制。
在這種特殊情況下,您可以通過使用getType
方法來確保該property
屬於Property<Integer>
類,因此可以安全地忽略該警告。
if (property.getType().equals("Integer")) {
// we have made sure property is of class Property<Integer> so the cast is type safe
@SuppressWarnings("unchecked")
Property<Integer> propInt = (Property<Integer>) property;
propInt.setValue((Integer) values[i++]);
}
重要的是要用注釋記錄下來,否則查看您的代碼的同行可能不會注意到確實類型轉換是安全的,並且可能將警告抑制作為不當行為加以混淆。
警告表明,在源級別,列表可能包含任何類型()的對象,並且將它們強制轉換為Integer,如果列表包含非Integer對象,則在運行時會導致ClassCastException。 因此,警告表明在運行時存在潛在問題。
您可以通過以下兩種方法擺脫警告
List<Integer>
@SuppressWarnings("unchecked")
警告。 如果不能保證列表中包含的對象不是Integer,則在轉換和SuppressWarning之前應該具有instanceof
。 如果可以保證,則應將該列表聲明為Integers列表。
您可以使用annotation SuppressWarnings
忽略此警告:
@SuppressWarnings("unchecked") Property<Integer> propInt = (Property<Integer>) property;
但是這樣做是有風險的。
此警告是由於類型擦除引起的,因為在編譯時, 泛型將被擦除。
如您所知,java中的泛型會遭受類型擦除,所有這些在運行時都變為Object。
當您對“ Integer”之Class<T>
字符串進行測試時,添加Class<T>
似乎更為方便。
class Property<T> {
final Class<T> type;
value T;
public Property(Class<T> type) {
this.type = type;
}
public void setAnyValue(Object value) {
this.value = type.cast(value);
}
}
Property<?> property = ...
//if (property.getType() == Integer.class) {
// Property<Integer> propInt = (Property<Integer>) property;
// propInt.setAnyValue((Integer) values[i++]);
//}
property.setAnyValue(values[i++]);
Object的使用歸因於Property的多態使用,而不是更普通的鍵入:您的代碼混合了不同類型的屬性和並行值。
import static org.springframework.data.util.CastUtils.cast;
Map<String,Object> messageMap = cast(exchange.getMessage().getBody());
List<String> refIds = cast(messageMap.get("refIds"));
除非spring框架已成為您應用程序的一部分,否則我不建議您使用此功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.