【问题标题】:Type Safety: Unchecked Cast from Object[] to T[]类型安全:从 Object[] 到 T[] 的未经检查的强制转换
【发布时间】:2013-11-03 19:39:17
【问题描述】:

当我用 Java 编写泛型类时,我使用下面的代码

public ResizableArray() {
    this.count=0;
    this.elements = (T[]) new Object[0];
}

但是我收到警告:

类型安全:从 Object[] 到 T[] 的未经检查的强制转换

为什么我会收到此警告?

【问题讨论】:

  • 如果您可以在此问题中添加更多代码以显示 可见的位置,将会提供更多信息。

标签: java generics generic-programming


【解决方案1】:

您正在创建一个 Object[](即“Object”类的实例数组,因此基本上是一个任何东西的数组)。您将其转换为 T[] (这是一个只能包含 T 类实例的数组)。您不测试数组中的对象(我知道没有,但编译器没有)实际上是否是 T - 如果不是,则强制转换将在运行时抛出 ClassCastException。这就是您收到警告的原因。

【讨论】:

  • 我怎样才能避免这种情况?
  • 你不能——至少在不改变一点的情况下不能。简单数组永远不是泛型的,因此您不能从泛型类型创建数组。如需更多建议,您需要向我们展示更多代码,以便我们从大局中了解是否、在何处以及可以更改的内容。
  • "如果不是,演员将在运行时抛出 ClassCastException" 不。
  • @newacct:不是吗?嗯,是!转换完成时不会抛出该异常,而是当您实际读取该数组中的对象时。
  • @JohannesH.:不。您可以很好地读取数组中的对象。只有将数组变量的类型暴露给外部才会出现问题。
【解决方案2】:

如果T 是除Object 之外的其他任何东西,那么您基本上是在沮丧地撒谎。这是因为 Java 数组的类型与泛型类型不同,是reified。换句话说,

boolean isStringArray(Object[] os) { return os instanceof String[]; }

调用

System.out.println(isStringArray(new Object[]));

实际上打印false:运行时知道数组的组件类型。

您真正想做的是return new T[],但您可能已经发现这是不允许的,并且由于上述泛型和数组类型之间的完全不匹配而不允许这样做。

【讨论】:

  • 这就是我使用这种向下转换的原因
猜你喜欢
  • 2022-02-03
  • 2013-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多