当前位置: 首页 > 知识库问答 >
问题:

为什么我不能将对象数组强制转换为泛型类的泛型子类的数组?

洪祺
2023-03-14

此代码有效。它以“未检查或不安全操作”警告进行编译和运行。

class Foo<T> {
  T[] items = (T[]) new Object[10];

  public static void main(String[] args) {
    Foo<Integer> foo = new Foo<Integer>();
  }
}

当这两个给我运行时错误时

class Foo<T> {
  class FooItem { T item; }

  FooItem[] items = (FooItem[]) new Object[10];

  public static void main(String[] args) {
    Foo<Integer> foo = new Foo<Integer>();
  }
}
class Foo<T> {
  static class FooItem<E> { E item; }

  FooItem<T>[] items = (FooItem<T>[]) new Object[10];

  public static void main(String[] args) {
    Foo<Integer> foo = new Foo<Integer>();
  }
}

我遇到的错误如下:

共有1个答案

姬泰
2023-03-14

您的foo类的所有版本都有同样的问题。您忽略的类型安全:Unchecked cast from object[]to x警告只显示了它在执行过程中不同阶段的后果。

以下是打破第一个版本的方法:

class Foo<T> {
    T[] items = (T[]) new Object[10];

    public static void main(String[] args) {
        Foo<Integer> foo = new Foo<Integer>();

        Integer i = foo.items[1] * 2;
    }
}

它和...同样的问题:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
    at stackoverflow.Foo.main(Main.java:17)

正如不能将new Object()强制转换为integer一样,也不能将new Object[10]强制转换为integer[]。只是这个类强制转换异常只在运行实际强制转换时才显示出来。对于第一个代码片段,它不是在声明语句t[]items=(t[])new object[10];(因此出现警告)上运行,而是在items用作t的类型参数时运行。

您的其他版本更早地显示了这个问题,只是因为它们强制转换为具体类型,如(Fooitem[])new Object[10],导致声明语句本身崩溃。
为什么编译器允许这种强制转换?因为类型关系是有效的,所以假定这样的代码

Object[] items = new Integer[10];
Integer[] i = (Integer[])items;
Integer val = i[0];

是有效和受支持的。

 类似资料:
  • 我正在创建一个由数组支持的泛型类型堆栈。当我尝试创建泛型类型数组时,Java不允许我这样做。有人告诉我,我必须创建一个类型为Object的数组,并将其转换为泛型类型。我已经将对象数组转换为类型,但如何处理Java不断给我的未检查类型错误? 这就是我目前所处的位置。 更新:我正在创建一个对象数组,然后在方法的末尾将返回类型转换为T类型。

  • 有没有一种简单的方法可以做到这一点: 编辑:我写了一份正确答案的工作副本:

  • 问题内容: 我正在制作一个类,以便模拟C ++中的函数指针的功能。最初,我只用s 做所有事情,但后来我有了一个想法- 为什么不使其真正通用? 问题出在这个构造函数上,该构造函数试图使用签名调用另一个构造函数: 我以为这会很好,但是我收到了以下编译器错误: 因此,我很困惑,我这样做: 现在可以编译,但是我收到以下警告: 我想问题是我不明白这意味着什么。我认为,由于从参数推断出的类型,因此有 必要 调

  • 我在我的一个实用程序类中有一个方法,它接受一个集合和一个类对象,并返回一个Iterable实例,该实例可以遍历作为指定类实例的集合的所有成员。其签名为: 这对于大多数用例都非常有效,但现在我需要将其与泛型类

  • 问题内容: 我正在使用泛型编写某些东西,令我惊讶的是,我发现这行不通: 那我不能实例化泛型吗?没有任何方法可以做到这一点吗? 问题答案: 是的,这真是令人讨厌。 我使用的解决方法是强制客户端在构造新类时传递类-即 然后您可以使用。

  • 我不想为每个类型T编写这个方法只是为了调用getMessage()并将其传递给下一个方法。 有可能写出这样的方法吗?我只想访问ConstraintViolation接口的方法,这些方法不依赖于类型T(如字符串getMessage())。