2017-03-23 3 views
0

私はストレステストの目的で任意のクラスのランダムジェネレータを作成しようとしています。 (反射による)クラス<?>がリフレクションで他のインスタンスになっているかどうかを確認する

私の発電目標がデフォルトコンストラクタを持つクラスを作成し、そのプリミティブと文字列フィールドを埋めるために

私はNumber型(整数、ロング、ダブル....)のフィールドを埋めるためにも希望それらは簡単にプリミティブに変換可能です。

しかし、タイプ間の簡単なアプローチo instanceofを見つけることができませんでした。問題を引き起こしものであればここで

は方法

public static <V> Collection<V> createMassiveCollection(Class<V> clazz, int amount, Class<?> collectionType) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { 

     Random r = new Random(); 
     RandomGenerator rg = new RandomGenerator(); 
     @SuppressWarnings("unchecked") 
     Collection<V> collection = (Collection<V>) collectionType.newInstance(); 
     for (int i = 0; i < amount; i++) { 
      V item = clazz.newInstance(); 

      for (Field field : item.getClass().getDeclaredFields()) { 

       if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) || java.lang.reflect.Modifier.isFinal(field.getModifiers())) 
        continue; 

       field.setAccessible(true); 

       if (field.getType().equals(String.class)) 
        field.set(item, rg.nextCompliment()); 

       else if (field.getType().isPrimitive() && (field.getType() != boolean.class && field.getType() != byte.class && field.getType() != char.class)) 
        field.set(item, r.nextInt(1000000)); 

       else { 
        Constructor<?> c = null; 

        try { 
         c = field.getType().getConstructor(String.class); 
        } 
        catch (Exception e) {} 
        if (c != null && Number.class.isInstance(c.newInstance("1"))) 
         field.set(item, field.getType().getConstructor(String.class).newInstance(r.nextInt(1000000) + "")); 
       } 

      } 

      collection.add(item); 
     } 
     return collection; 
    } 

第三である 私のような何かをしたいと思います: 「Type<C>Type<V>のサブタイプがある場合は、」しかし、すべての方法は、私は、オブジェクトの有効なインスタンスを必要としましたチェックする。

ex。 field.getType()がTypeのインスタンスであるため、 Number.class.isInstance(field.getType())でもfield.getType() instanceof Numberが機能します。

誰でも知ることができますか?

もう一つの問題(重要度の低い)私のメソッドシグネチャで私は

Class<? extends Collection<V>> collectionType 

を持っていると思いますが、私は

createMassiveCollection(User.class, 100000, new ArrayList<User>().getClass()); 

のようなメソッドを呼び出すようにしようとすると、コンパイラが失敗したことを行うと!コンパイルできるようにするには、ユーザがCollectionをパラメータとして継承する型を渡していると信じなければならない

+0

'new ArrayList ().getClass()'は常に* erase * type 'Class <?を返します。 extends ArrayList > 'のように、' Class <? Collection > '' unsafe ''キャスティングで拡張しました。そして、実際にはそれを行う必要はありません。なぜなら、 'Class <? extendsコレクション> 'はあなたのニーズに完全に適しています:とにかく新しいコレクションを作成して記入すると、そのコレクションタイプが' 'なら本当に気になる人ですか? –

答えて

1

を出力:

public static <V, C extends Collection<?>> Collection<V> createMassiveCollection(Class<V> clazz, int amount, Class<C> collectionType) 

この汎用コードはC extends Collection<V>とも定義できますが、これはコンパイラの警告を生成し、createMassiveCollection(String.class, 10, new ArrayList<Number>().getClass())のような呼び出しを防止しません。

ところで、私の最後のパラメータはArrayList.classになります。

0

チェックClass#isAssignableFrom()これは、あるクラスが別のクラスのサブタイプであるかどうかを判断できるようにします。例:あなたが第二ジェネリックを必要とする、あなたの第二の質問については

if (Number.class.isAssignableFrom(field.getType()) { // ... 

System.out.println(String.class.isAssignableFrom(Object.class)); 
System.out.println(Object.class.isAssignableFrom(String.class)); 

それはクラスを使用すると、isAssignableFromを使用する必要があり、別のサブクラスであるかどうかを確認するには

false 
true 
1
  1. field.getType()戻り値Class<?>です。 typeというプロパティー名は、ジェネリックスがなく、したがってTypeインターフェースがない場合、Java 1に由来します。それは最初の一見で混乱するかもしれません。Class<?>が表すクラスを使用すると、classA.isAssignableFrom(classB)を使用する必要がありますClass<?>別で表されるクラスのサブタイプであるかどうかをテストするには

  2. 。例えばNumber.class.isAssignableFrom(Integer.class)がtrueを返します。

  3. Class<? extends Collection<V>> collectionTypeと書くことは可能ですが、明示的に安全でないキャストなしでClass<? extends Collection<V>>のインスタンスを取得できないためです。

    1. Attempting to write class literals of generic types, except a wildcard type, will result in compile time errors.
    2. Object.getClass()ので消去タイプを返します。例えばnew ArrayList<User>().getClass()の戻り値の型は、ArrayListまたはArrayList<?>であり、その意味は同じです。

    明示的に安全でないキャストがなければ、このメソッドはVがワイルドカードの場合にのみ呼び出すことができます。

関連する問題