2016-09-21 5 views
0

ArrayBasedStackのメソッドの1つであるtoArrayメソッドのjunitテストを記述しています。このクラスは内部に配列を持ち、toArrayメソッドは要素をコピーして返します。メソッドはクラスによって与えられ、配列の各要素を出力しようとしています。ClassCastException toArray()メソッドの使用

このメソッドはローカル配列をコピーし、オブジェクトの型を持つコピー配列を返します。テストのために

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

、私は以下のようなとしてString配列を設定します。

プライベートArrayBasedStackスタックを、 toArray()メソッドをテストする

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

を、他のメソッドのテストのようなよく渡さ: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) 
+4

さて、あなたは 'Object []'を作成していて、それを呼び出すと効果的に 'String []'にキャストされ、そのキャストは無効です。基本的に、実行時に実際に要素の型を知らなくても、正しい種類の配列を作成することはできません。 –

+0

'Arrays.copyOf()'を使って内部配列をコピーしたとお考えですか?あなたはそのように*真実* 'T []'(つまり 'String []')を得ることができます。キャスティングは必要ありません。 –

+1

これは参考になるかもしれません:http://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java – uoyilmaz

答えて

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

あなたはコンパイラに嘘をついています。 T[]Object[]でない限り、T[]ではありません。

このメソッドを作成する正しい方法は、あなたが幸運ならば、プロトタイプを供給することにより、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()); 
} 
関連する問題