Java:未选中从X转换为Y /如何实现castOrNull
我已经实现了这个function:
static Y castOrNull(X obj) { try { return (Y)obj; } catch(ClassCastException e) { return null; } }
这给了我编译器警告:
Type safety: Unchecked cast from X to Y
我不太明白。 不是我在这里做的try/catch
检查吗? 我可以忽略这个警告吗?
我的function是否会按预期工作? 我该如何正确实现它?
我也尝试使用obj instanceof Y
检查的obj instanceof Y
但由于Java处理generics的方式,这不起作用。
顺便说一句,这个函数对我来说似乎非常有用(使其他代码更干净)。 我想知道Java中是否已存在这样的函数?
我想要使用它的一个例子:
void removeEmptyRawStrings() { for(Iterator e = entities.iterator(); e.hasNext();) { RawString s = castOrNull(e.next()); if(s != null && s.content.isEmpty()) e.remove(); } }
我的代码中经常出现类似这样的情况。 而且我认为这比其他任何东西都更具可读性和简单性。 但是,如果你有任何关于如何使代码更简单的话,请给我一个更好的建议。
所以这里的问题是用于动态转换的generics参数Y
被视为Object
。 它永远不会抛出CCE。 你在调用方法中抛出一个CCE,因为你破坏了静态类型的安全性。
X
在这里完全没有意义:
几乎可以肯定,正确的解决办法不是尝试这样的事情。 null
很糟糕。 施法很糟糕。
但是,如果您决定编写废话,则可以传递Class
对象:
public static T evilMethod(Class clazz, Object obj) { try { return clazz.cast(obj); } catch (ClassCastException exc) { return null; } }
我不完全确定它能按预期工作。 (取决于你期望的当然:-)但是这段代码将导致java.lang.ClassCastException
( ideone ):
public class Main { public static void main(String[] args) { Integer o = Main.castOrNull("hello"); } public static Y castOrNull(X obj) { try { return (Y) obj; } catch (ClassCastException e) { return null; } } }
@Tom Hawtin得到了“正确”的解决方案 。
如果您通过使用@SuppressWarnings("unchecked")
对其进行注释来确定它不是问题,则可以取消此方法中的警告
感谢java generics的设计方式,这个代码根本不起作用。 generics仅对编译时类型检查有用,因为类在运行时不使用generics类型信息。
您的代码将编译为:
static Object castOrNull(Object obj) { try { return (Object)obj;//FAIL: this wont do anything } catch(ClassCastException e) { return null; } }
对Object的强制转换永远不会失败,并且编译后的代码无法访问编译时出现的generics类型。 由于演员阵容不会发生,因此您应该收到未经检查操作的警告。