Java:从X到Y的未检查的演员
-
30-09-2019 - |
题
我已经实现了此功能:
static <X,Y> Y castOrNull(X obj) {
try {
return (Y)obj;
}
catch(ClassCastException e) {
return null;
}
}
这给了我编译器警告:
Type safety: Unchecked cast from X to Y
我不完全理解。不是 try/catch
我在这里做的检查?我可以忽略警告吗?
我的功能会正常工作吗?我将如何正确实施?
我也尝试了 obj instanceof Y
检查,但由于Java处理通用物质的方式,这无效。
顺便说一句,此功能对我来说似乎很有用(使其他代码更加干净)。我想知道Java中是否已经存在这样的功能?
我想使用它的一个示例:
void removeEmptyRawStrings() {
for(Iterator<Entity> e = entities.iterator(); e.hasNext();) {
RawString s = castOrNull(e.next());
if(s != null && s.content.isEmpty()) e.remove();
}
}
我的代码经常有这样的案例。而且我认为这比其他任何事情都更可读和简单。但是,如果您对如何使该代码更加简单,请给我一个更好的建议。
解决方案
因此,这里的问题是通用参数 Y
当用于动态铸造时被视为 Object
. 。它永远不会抛出CCE。你会被扔在 打电话 方法,因为静态型安全性破裂。
还 X
在这里完全毫无意义:
几乎可以肯定的是,正确的解决方案不是尝试这样的事情。 null
不好。铸造很糟糕。
但是,如果您决心写废话,则可以通过 Class
目的:
public static <T> T evilMethod(Class<T> clazz, Object obj) {
try {
return clazz.cast(obj);
} catch (ClassCastException exc) {
return null;
}
}
其他提示
我不确定它会按预期工作。 (取决于您的期望:-)但是,例如,此代码将导致 java.lang.ClassCastException
(伊德尼):
public class Main {
public static void main(String[] args) {
Integer o = Main.<String, Integer>castOrNull("hello");
}
public static <X, Y> Y castOrNull(X obj) {
try {
return (Y) obj;
} catch (ClassCastException e) {
return null;
}
}
}
@Tom Hawtin得到了 “正确”解决方案.
如果您确定通过注释这不是问题,则可以在此方法中抑制警告 @SuppressWarnings("unchecked")
多亏了Java Generics设计该代码根本无法正常工作的方式。仿制药仅对编译时间类型检查有用,因为类在运行时不使用通用类型信息。
您的代码将被编译为:
static Object castOrNull(Object obj) {
try {
return (Object)obj;//FAIL: this wont do anything
}
catch(ClassCastException e) {
return null;
}
}
对象的演员将永远不会失败,并且编译的代码无法访问编译时存在的通用类型。由于演员阵容不会像您收到未经检查操作的警告那样发生。
不隶属于 StackOverflow