簡體   English   中英

檢查是否有班級 <?> 通過反思是其他的本能

[英]Checking if a Class<?> is instane of other by reflection

我正在嘗試為壓力測試目的創建任何類的隨機生成器。

我的生成器目標是使用默認構造函數創建任何類並填充其原始字符串和字符串字段(通過反射)

我還想填充Number(Integer,Long,Double ....)類型的字段,因為它們很容易轉換為原語。

但我無法找到一個簡單的方法Ø 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;
    }

第三個if是導致問題的那個我想要的東西:“如果Type<C>Type<V>Type<V> ”但是我找到的所有方法都需要一個有效的對象實例來檢查。

恩。 Number.class.isInstance(field.getType())field.getType() instanceof Number起作用,因為field.getType()是Type的實例。

有誰知道這是否可能?

我想要的方法簽名中的另一個問題(不太重要)

Class<? extends Collection<V>> collectionType

但如果我這樣做,當我嘗試調用方法時

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

編譯器失敗了! 所以,為了能夠編譯我必須相信用戶正在傳遞一些擴展Collection作為參數的類型

要檢查某個類是否是另一個類的子類,您必須使用isAssignableFrom

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

對於你的第二個問題,你需要第二個通用:

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

  1. field.getType()返回Class<?> type屬性名稱來自Java 1,當沒有泛型且因此沒有Type接口時。 乍一看可能會令人困惑。

  2. 要測試Class<?>表示的類是否是由另一個Class<?>表示的類的子類型,您需要使用classA.isAssignableFrom(classB) 例如, Number.class.isAssignableFrom(Integer.class)將返回true。

  3. Class<? extends Collection<V>> collectionType有可能但沒有意義Class<? extends Collection<V>> collectionType Class<? extends Collection<V>> collectionType ,因為你無法獲得Class<? extends Collection<V>>的實例Class<? extends Collection<V>> Class<? extends Collection<V>>沒有明確的不安全強制轉換。 因為

    1. 嘗試編寫泛型類的類文字(通配符類型除外)將導致編譯時錯誤。
    2. Object.getClass()將返回已擦除的類型。 例如, new ArrayList<User>().getClass()的返回值的類型將是ArrayListArrayList<?> ,其含義相同。

    如果沒有明確的不安全轉換,只有在V是通配符時才能調用此方法。

檢查Class#isAssignableFrom() ,它允許確定一個類是否是另一個類的子類型。 例:

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

它輸出

false
true

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM