0

I am writing junit test for toArray method which is one of the method of ArrayBasedStack. This class has an array inside and toArray method copies the element and return. The method is given by the class, and I amd trying to print out each element in the array.

This method copy the local array and return the copy array with the type of the 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;
}

For the test, I set up String array as like below:

private ArrayBasedStack stack;

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

To test toArray() method, I tried:

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

Other than toArray() method, other methods' test passed well such as: peek(), push(), clear(), equals()... etc.

However, only this test returns error for both assertEquals:

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

The error is:

>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)
3
  • 4
    Well yes, you're creating an Object[], and then when you call it, that's effectively casting to String[], and that cast isn't valid. Basically, you can't create the right kind of array without actually knowing the element type at execution time. Commented Sep 21, 2016 at 21:08
  • Have you considered using Arrays.copyOf() to copy the internal array? You should be able to get a bona fide T[] (i.e. String[]) that way. And no casting needed. Commented Sep 21, 2016 at 21:14
  • 1
    This may be helpful: stackoverflow.com/questions/529085/… Commented Sep 21, 2016 at 21:20

1 Answer 1

2
    T[] copy = (T[]) new Object[this.size()];

Here you are lying to the compiler. It isn't a T[], unless T[] is Object[].

The correct way to write this method is the same way Collections do it, by supplying a prototype that if you're lucky is already the right size:

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;
}

or alternatively:

import java.util.Arrays;

public T[] toArray(T[] a)
{
    return Arrays.copyOf(this.myArray, this size());
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.