【问题标题】:Problems with casted generic array铸造通用数组的问题
【发布时间】:2013-07-29 15:46:38
【问题描述】:

我阅读了我发现的每一篇提出这个问题的帖子,但我无法将它们都适用于我为这项任务所做的事情。首先,我必须使用一个数组。其次,包含泛型数组的类正在被其他类访问和使用。所以虽然我可以编译类似的东西:

T[] arr = (T[]) new Object[15];

当我尝试运行使用此数据结构的任何其他类时,我收到无法强制转换的错误。

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; can
not be cast to [Ljava.lang.Comparable;

我阅读的解决方案或变通方法主要是使用 Array.newInstance() 创建类并将其转换为泛型类型 T[]。我遇到的问题是我不知道我会用这个方法使用什么类。没有任何东西传递给我的构造函数。

我最初的解决方法是将数组实例化为字符串并转换为 T[]。这行得通,我的课程被编译,我的小驱动程序完美执行。但是现在我正在编写另一个使用新数据结构的类,然后将其输入到这个数据结构中。当我尝试向数组中添加任何内容时,它会中断。

Exception in thread "main" java.lang.ArrayStoreException: DATATYPE

当我尝试将它添加到原始类中的数组时,错误给了我一行:

store[length] = item;

item 以

的形式传递给 add 方法
T item

这里有什么我遗漏的吗?我想我可以将它转换为 T[] 然后用通用项目 T 填充它。

编辑:这是 add 方法和类的相关部分:

public class AThreadedBSTree<T extends Comparable<? super T>> implements        
    ThreadedBSTreeInterface<T>, Cloneable
{

    public void add(T item)
    {
          ensureCapacity();

          store[length] = item;
    }
}

这是我用来测试不同数据结构的 add 方法的代码:

 public class Driver 
 {
      public static void main(String args[]) 
      {
            Scanner in = new Scanner(System.in);
            Datatype test = new Datatype(in);
            AThreadedBSTree<Datatype> tree = new AThreadedBSTree<Datatype>();
            tree.add(test);
      }
 }

【问题讨论】:

  • 请贴出你使用的方法
  • 请发布完整的泛型方法、调用方式以及用于获取此类异常的示例数据。换句话说,SSCCE :)
  • “不要使用Object[],而是使用T[]” - 这会从哪里开始受到伤害。向我们展示那个地方,可能会出现一些解决方案,例如前面提到的 Array 和 Arrays。
  • 对不起。添加了一些代码,如果还有更多,请告诉我。真的很沮丧,因为我以为我已经完成了这项任务,现在我无法完成最简单的最后一部分。
  • 真的,最简单的方法就是使用 ArrayList,它会为您完成必要的转换。

标签: java arrays generics


【解决方案1】:

你可以试试

 T[] store = (T[]) Array.newInstance(Comparable.class, size);

用于您的后备数组,而不是使用 Object 数组。这不会产生您正在经历的ClassCastException。据我所知,它也不应该产生任何ArrayStoreException(至少在我的小测试中没有得到任何结果)。

当然,创建T 的数组会更好,但唯一的方法是获取对Class&lt;T&gt; 的引用(可能通过构造函数参数)并在Array.newInstance(...) 中使用它。

【讨论】:

  • 尝试此操作时,出现错误。 错误:找不到符号存储 =(T[]) Array.newInstance(Comparable.class, 12); ^ 符号:变量数组
  • 您是否正确导入了Array 类?它位于java.lang.reflect.Array
  • 我以为我有,但我想没有。谢谢。
  • 正如 Chamly Idunil 指出的那样,您可以只使用 T[] store = (T[]) new Comparable[size];。这可能是一个更好的主意。
  • 没有必要将Array.newInstance() 与类文字一起使用。只需使用new Comparable[size]
【解决方案2】:

你必须在 Driver 类上实现 Comparable。

public class Driver implements Comparable<Driver>

并使用它来初始化数组。

T[] arr = (T[]) new Comparable[15];

【讨论】:

    【解决方案3】:

    这段代码实现了与数组转换相同的结果:

    @SuppressWarnings({"unchecked"})
    public <T> T[] cast(Object[] array, Class<T> type)
    {
      T[] castArray = (T[])Array.newInstance(type, array.length);
    
      for (int i = 0; i < array.length; i++)
      {
        castArray[i] = (T)array[i];
      }
    
      return castArray;
    }
    

    您显然需要小心,因为很容易获得 java.lang.ClassCastException,但即使您可以直接转换原始数组,您也会期望得到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-16
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多