我有一个Class
变量,它包含某种类型,我需要获取一个包含相应数组类的变量。我能想到的最好的是:
Class arrayOfFooClass = java.lang.reflect.Array.newInstance(fooClass, 0).getClass();
有没有办法在不创建新实例的情况下执行此操作?
答案 0 :(得分:16)
如果您不想创建实例,可以手动创建数组的规范名称并按名称获取类:
// Replace `String` by your object type.
Class stringArrayClass = Class.forName(
"[L" + String.class.getCanonicalName() + ";"
);
但是Jakob Jenkov argues in his blog你的解决方案更好,因为它不需要摆弄字符串。
Class stringArrayClass = Array.newInstance(String.class, 0).getClass();
答案 1 :(得分:8)
自Java 12起,就有arrayType()
method on java.lang.Class。这样:
Class<?> arrayOfFooClass = fooClass.arrayType();
答案 2 :(得分:0)
所以,我想一想,喜欢摆弄弦乐。因此,这是采用该方法的更通用的解决方案,并且仍然适用于任意类类型。它肯定比您的答案更有趣,但是无论如何,使其通用而不是公认的答案要复杂,因此这里是使它起作用的完整代码集:
/**
* 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方法的原因。可以修改它以保留点而不是/,但是鉴于其工作原理,我在两种方法之间来回转换。无论如何,这适用于任何类,包括嵌套数组类型。
答案 3 :(得分:0)
您可以使用类名获取它。 只需确保使用ClassLoader来获取该类
Class klass = yourClass;
boolean init = wantToDoStaticOperations;
Class.forName("[L" + klass.getName() + ";", init, klass.getClassLoader());
答案 4 :(得分:-1)
Class stringArrayOfClass = String[].class;