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类型。 由于演员阵容不会发生,因此您应该收到未经检查操作的警告。