1

内部配列(データなど)と配列内の要素数(Nなど)(両方ともプライベート)を維持するジェネリッククラスがあります。配列に要素を追加すると、Nの値が更新されます。このクラスには、データ配列または N の get メソッドがありません。それでも、配列と N の状態をチェックするための単体テストを書きたいと思います。

    public class InternalArray<T> {
    private T[] data;
    private int N;
    private int head;
    public InternalArray() {
        super();
        data = (T[]) new Object[10];
        N = 0;
        head = 0;
    }

    public void add(T item){
        data[head]=item;
        head++;
        N++;
    }

    public T get(){
        T item = data[--head];
        N--;
        return item;
    }
}

ここでテストできるのはパブリック API だけです。ただし、プライベート変数の内部状態をテストする必要があります。リフレクションを使用してフィールドにアクセスできると思いました。以下のコードを試してみましたが、N の値を取得できます。T[] データに関しては、結果ObjectString[](電話からarrayf.get(inst)

public static void demoReflect(){
        try {           
                Class t = Class.forName("InternalArray");
                System.out.println("got class="+t.getName());
                InternalArray<String> inst = (InternalArray<String>) t.newInstance();
                System.out.println("got instance="+inst.toString());

                inst.add("A");
                inst.add("B");
                Field arrayf = t.getDeclaredField("data");
                arrayf.setAccessible(true);
                Field nf = t.getDeclaredField("N");
                nf.setAccessible(true);
                System.out.println("got arrayfield="+arrayf.getName());
                System.out.println("got int field="+nf.getName());
                int nval = nf.getInt(inst);
                System.out.println("value of N="+nval);
                Object exp = arrayf.get(inst);
                //how to convert this to String[] to compare if this is {"A","B"}

        } catch (ClassNotFoundException e) {            
            e.printStackTrace();
        } catch (InstantiationException e) {            
            e.printStackTrace();
        } catch (IllegalAccessException e) {            
            e.printStackTrace();
        } catch (SecurityException e) {         
            e.printStackTrace();
        } 
        catch (IllegalArgumentException e) {            
            e.printStackTrace();
        } catch (NoSuchFieldException e) {          
            e.printStackTrace();
        }
    }

これにより、以下の出力が得られました

got class=InternalArray
got instance=InternalArray@c2ea3f
got arrayfield=data
got int field=N
value of N=2
4

1 に答える 1

2

Object呼び出しから得られるarrayf.get(inst)は、タイプObject[]ではなくString[]です。これは、Java ジェネリックがタイプ消去によって実装されているためです。あなたはこれを行うことができます:

Object[] strings = (Object[])arrayf.get(inst);
System.out.println(strings.length);
for (int i = 0 ; i != strings.length ; i++) {
    String s = (String)strings[i];
    ...
}

PS実装のプライベートな詳細を単体テストするのが良い考えかどうかについての議論には近づかないつもりです。

于 2013-09-13T15:25:20.883 に答える