繁体   English   中英

类型安全:从Object中取消选中强制转换

[英]Type safety: Unchecked cast from Object

我尝试将一个对象强制转换为我的Action类,但它会产生一个警告:

Type safety: Unchecked cast from Object to Action<ClientInterface>

Action<ClientInterface> action = null;
try {
 Object o = c.newInstance();
 if (o instanceof Action<?>) {
  action = (Action<ClientInterface>) o;
 } else {
  // TODO 2 Auto-generated catch block
  throw new InstantiationException();
 }
 [...]

感谢您的任何帮助

是的 - 这是类型擦除的自然结果。 如果o实际上是一个不会被强制转换捕获的Action<String>实例 - 当你尝试使用它时,你只能看到问题,传入ClientInterface而不是字符串。

您可以使用以下命令摆脱警告:

@SuppressWarnings("unchecked")

作为函数注释,但你不能轻易地解决潜在的问题:(

像往常一样,Jon Skeet是对的。

详细说明他答案的不易部分:

特定

class ClientAction implements Action<ClientInterface> {}

你可以写:

Class<? extends Action<ClientInterface>> c = ClientAction.class;
Action<ClientInterface> action = c.newInstance();

这样可以消除强制转换和警告,但代价是引入非泛型类型,因此您可以使用.class来获得足够准确的类型Class对象。

警告意味着即使在运行时铸件工作正常,编译器也无法保证类型安全。 由于擦除,在运行时,转换只是对Action的转换。 底层泛型类可能不是预期的ClientInterface类型。 在这种情况下,问题将在稍后(可能甚至更晚)出现,作为ClassCastException。

在这种特定情况下,我建议通过以下编译器指令来抑制此特定警告:

@SuppressWarnings("unchecked")

别担心。 这是因为Java编译器无法知道对象的真实类型是什么。

由于擦除(即参数化类型已被删除),您丢失了类型信息,因此发出警告。 除了清理周围的代码以便更频繁地使用泛型之外,您无法对此做任何事情,因此您可以传递泛型类型信息并完全避免转换。

这是一个沮丧的人。 这是动态转换,编译器不知道引用指向的实际对象。

您收到此警告是因为Action<ClientInterface>的目标类型是参数化类型 ,并且编译器无法保证类型转换的对象属于同一类型。

如果您不想取消此警告而不关心type参数,可以使用通配符将代码更改为:

Action<?> action = null;
try {
 Object o = c.newInstance();
 if (o instanceof Action<?>) {
  action = (Action<?>) o;
 } else {
  // TODO 2 Auto-generated catch block
  throw new InstantiationException();
 }
 [...]

这样更安全,因为instanceof无法检查o是否是Action<ClientInterface>的对象,它只是检查o是否是Action的对象,因为在运行时将删除更多泛型类型信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM