[英]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.