English 中文(简体)
How to get the Array Class for a given Class in Java?
原标题:

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this:

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

Is there a way to do this without creating the new instance?

最佳回答

Since Java 12, there is the arrayType() method on java.lang.Class. With that:

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

The implementation of Class.arrayType() just calls Arrays.newInstance(this, 0).getClass().

问题回答

Since Java 12

Class provides a method arrayType(), which returns the array type class whose component type is described by the given Class. Please be aware that the individual JDK may still create an instance of that Class³.

Class<?> stringArrayClass = FooBar.arrayType()

Before Java 12

If you don t want to create an instance, you could create the canonical name of the array manually and get the class by name:

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

But Jakob Jenkov argues in his blog that your solution is the better one, because it doesn t need fiddling with strings.

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

³ Thanks for the hint to Johannes Kuhn.

You can get it using the class name. Just make sure you get the class using it s ClassLoader

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

So, I for one, like fiddling with Strings. So, here s a more general solution that takes that approach, and still works with arbitrary class types. It is certainly more fiddly than your answer, but anyways, it s more complex to make it generic than the accepted answer gives it credit for, so here is the complete set of code to make it work:

    /**
     * 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());
        }
    }

Note that this is code from an existing library I wrote, which is why I make use of the getJVMName method. It could probably be modified to keep the dots instead of the /, but given that s how it works, I convert back and forth between the two methods. Anyhow, this works with any class, including nested array types.

Class stringArrayOfClass = String[].class;




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

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

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签