【问题标题】:ClassCastException from using toArray() method使用 toArray() 方法引发的 ClassCastException
【发布时间】:2016-09-21 21:06:05
【问题描述】:

我正在为 toArray 方法编写 junit 测试,这是ArrayBasedStack 的方法之一。该类内部有一个数组,toArray 方法复制元素并返回。该方法由类给出,我正在尝试打印出数组中的每个元素。

该方法复制本地数组,并返回复制的数组与Object的类型。

public T[] toArray() {
    T[] copy = (T[]) new Object[this.size()];
    for (int i = 0; i < this.size(); i++) {
        copy[i] = (T) this.myArray[i];
    }

    return copy;
}

为了测试,我设置了如下的字符串数组:

私有 ArrayBasedStack 堆栈;

public void setUp(){
    stack = new ArrayBasedStack<String>();
}

为了测试 toArray() 方法,我尝试了:

   public void testToArray(){
        stack.push("000");
        stack.push("111");
        assertEquals(2, stack.toArray().length);
        assertEquals("111", stack.toArray()[0]);
    }

除了 toArray() 方法之外,其他方法的测试都很好,例如:peek()、push()、clear()、equals()...等。

但是,只有这个测试对assertEquals 都返回错误:

    assertEquals(2, stack.toArray().length);
    assertEquals("111", stack.toArray()[0]);

错误是:

>java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
        at arraystack.ArrayBasedStackTest.testToArray(ArrayBasedStackTest.java:82)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
        at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298)
        at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

【问题讨论】:

  • 嗯,是的,您正在创建一个Object[],然后当您调用它时,它实际上是转换为String[],并且该转换无效。基本上,如果在执行时不知道元素类型,就无法创建正确类型的数组。
  • 你考虑过使用Arrays.copyOf()复制内部数组吗?您应该能够以这种方式获得善意 T[](即String[])。并且不需要铸造。
  • 这可能会有所帮助:stackoverflow.com/questions/529085/…

标签: java


【解决方案1】:
    T[] copy = (T[]) new Object[this.size()];

你在对编译器撒谎。它不是T[],除非T[] 是Object[]。

编写此方法的正确方法与Collections 的方法相同,提供一个原型,如果幸运的话,它的尺寸已经合适:

import java.lang.ref.Array;

public T[] toArray(T[] a)
{
    if (a.length != this.size())
    {
        a = Array.newInstance(a.getClass().getComponentType(), this.size());
    }
    for (int i = 0; i < this.size(); i++)
    {
        a[i] = (T) this.myArray[i];
    }
    return a;
}

或者:

import java.util.Arrays;

public T[] toArray(T[] a)
{
    return Arrays.copyOf(this.myArray, this size());
}

【讨论】:

    猜你喜欢
    • 2014-01-18
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 2015-11-10
    • 1970-01-01
    相关资源
    最近更新 更多