通过反射检查Class <! - ? - >是否是其他的instane

时间:2017-03-23 08:56:42

标签: java generics reflection instanceof typeof

我正在尝试为压力测试目的创建任何类的随机生成器。

我的生成器目标是使用默认构造函数创建任何类并填充其原始字符串和字符串字段(通过反射)

我还想填充Number(Integer,Long,Double ....)类型的字段,因为它们很容易转换为原语。

但我找不到类型之间的简单方法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>的子类型” 但我发现的所有方法都需要一个有效的对象实例来检查。

离。 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作为参数

的类型

3 个答案:

答案 0 :(得分:2)

要检查某个类是否是另一个类的子类,您必须使用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 :(得分:1)

  1. field.getType()返回Class<?>。 {1}}属性名称来自Java 1,当没有泛型且没有type接口时。乍一看可能会令人困惑。

  2. 要测试Type所代表的班级是否是另一个Class<?>所代表的班级的子类型,您需要使用Class<?>。例如classA.isAssignableFrom(classB)将返回true。

  3. 编写Number.class.isAssignableFrom(Integer.class)可能但毫无意义,因为如果没有明确的不安全强制转型,您无法获得Class<? extends Collection<V>> collectionType的实例。因为

    1. Attempting to write class literals of generic types, except a wildcard type, will result in compile time errors.
    2. Class<? extends Collection<V>>将返回已删除的类型。例如Object.getClass()的返回值类型为new ArrayList<User>().getClass()ArrayList,其含义相同。
    3. 如果没有明确的不安全强制转换,只有在ArrayList<?>是通配符时才能调用此方法。

答案 2 :(得分:0)

检查#!/usr/bin/python # This program is to find the prime numbers in the given range x = input ('Please enter the start range number: ') y = input ('Please enter the end range number: ') # validating the start range value should be greater than the end range value if x < y: for num in range(x, y): # validating the start range value greater than 1 if num < 1: print 'Please enter Starting numeric value more than 1' break elif num > 1: for i in range(2, num): if (num % i) == 0: break else: print (str(num) + ",") else: print 'Please enter Start Range Number value more than one' print 'Start Range Number should be lesser than End Range Number value' ,它允许确定一个类是否是另一个类的子类型。例如:

Class#isAssignableFrom()

输出

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