繁体   English   中英

如何在 Java 中获取给定类的数组类?

[英]How to get the Array Class for a given Class in Java?

我有一个包含某种类型的Class变量,我需要获取一个包含相应数组类的变量。 我能想到的最好的办法是:

Class arrayOfFooClass = java.lang.reflect.Array.newInstance(fooClass, 0).getClass();

有没有办法在不创建新实例的情况下做到这一点?

如果不想创建实例,可以手动创建数组的规范名称并按名称获取类:

// Replace `String` by your object type.
Class stringArrayClass = Class.forName(
    "[L" + String.class.getCanonicalName() + ";"
);

但是Jakob Jenkov 在他的博客中认为您的解决方案是更好的解决方案,因为它不需要摆弄字符串。

Class stringArrayClass = Array.newInstance(String.class, 0).getClass();

从 Java 12 开始, java.lang.Class 上arrayType()方法 接着就,随即:

Class<?> arrayOfFooClass = fooClass.arrayType();

您可以使用类名获取它。 只要确保你使用它的 ClassLoader 来获取类

    Class klass = yourClass;
    boolean init = wantToDoStaticOperations;
    Class.forName("[L" + klass.getName() + ";", init, klass.getClassLoader());
Class stringArrayOfClass = String[].class;

所以,我喜欢摆弄字符串。 所以,这里有一个更通用的解决方案,它采用这种方法,并且仍然适用于任意类类型。 它肯定比您的答案更繁琐,但无论如何,使其通用比公认的答案更复杂,因此这是使其工作的完整代码集:

    /**
     * Returns the name of the class, as the JVM would output it. For instance, for an int, "I" is returned, for an
     * array of Objects, "[Ljava/lang/Object;" is returned. If the input is null, null is returned.
     *
     * @param clazz
     * @return
     */
    public static String getJVMName(Class clazz) {
        if(clazz == null) {
            return null;
        }
        //For arrays, .getName() is fine.
        if(clazz.isArray()) {
            return clazz.getName().replace('.', '/');
        }
        if(clazz == boolean.class) {
            return "Z";
        } else if(clazz == byte.class) {
            return "B";
        } else if(clazz == short.class) {
            return "S";
        } else if(clazz == int.class) {
            return "I";
        } else if(clazz == long.class) {
            return "J";
        } else if(clazz == float.class) {
            return "F";
        } else if(clazz == double.class) {
            return "D";
        } else if(clazz == char.class) {
            return "C";
        } else {
            return "L" + clazz.getName().replace('.', '/') + ";";
        }
    }

    /**
     * Generically and dynamically returns the array class type for the given class type. The dynamic equivalent of
     * sending {@code String.class} and getting {@code String[].class}. Works with array types as well.
     * @param clazz The class to convert to an array type.
     * @return The array type of the input class.
     */
    public static Class<?> getArrayClassFromType(Class<?> clazz) {
        Objects.requireNonNull(clazz);
        try {
            return Class.forName("[" + getJVMName(clazz).replace('/', '.'));
        } catch(ClassNotFoundException ex) {
            // This cannot naturally happen, as we are simply creating an array type for a real type that has
            // clearly already been loaded.
            throw new NoClassDefFoundError(ex.getMessage());
        }
    }

请注意,这是我编写的现有库中的代码,这就是我使用 getJVMName 方法的原因。 它可能会被修改以保留点而不是 /,但鉴于它是如何工作的,我在两种方法之间来回转换。 无论如何,这适用于任何类,包括嵌套数组类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM