有谁知道在 Java 中是否可以获取具有“先验”未知维数的数组的维数?也就是说,如果不知道多维矩阵的维数,如果可能的话,如何检索它?
我不确定我是否正确理解了您要完成的工作。如果您只想知道数组中有多少个元素,Anubian 的答案是正确的。但我的理解是,你想计算给定通用数组的维数。
public class Test {
public static int getNumberOfDimensions(Class<?> type) {
if (type.getComponentType() == null) {
return 0;
} else {
return getNumberOfDimensions(type.getComponentType()) + 1;
}
}
public static void main(String[] args) {
System.out.println(getNumberOfDimensions(int[][][].class) == 3);
System.out.println(getNumberOfDimensions(int[][].class) == 2);
System.out.println(getNumberOfDimensions(int[][][][].class) == 4);
System.out.println(getNumberOfDimensions(int.class) == 0);
}
}
如果这不是您想要的,我会提示:length 和 dimension 之间存在差异。
更新:我认为这与我们被问到的完全无关,但 Nicola 在 cmets 中问我:
这很好用,但是如果在运行时定义了维度的数量(例如,用户必须输入所需的维度数量)呢?如何定义和初始化数组?
解决方案在于一些基于光反射的黑客攻击:
import java.lang.reflect.Array;
public class Test {
public static Class<?> getArrayType(Class<?> componentType, int dimensions) throws ClassNotFoundException {
if (dimensions == 0) {
return componentType;
}
String rawName = componentType.getName();
switch (rawName) {
case "byte": rawName = "B"; break;
case "char": rawName = "C"; break;
case "double": rawName = "D"; break;
case "float": rawName = "F"; break;
case "int": rawName = "I"; break;
case "long": rawName = "J"; break;
case "short": rawName = "S"; break;
case "boolean": rawName = "Z"; break;
default:
rawName = "L" + rawName + ";";
break;
}
for (int i = 0; i < dimensions; i++) {
rawName = "[" + rawName;
}
return Class.forName(rawName);
}
public static Object createArray(Class<?> componentType, int dimensions, int length) throws NegativeArraySizeException, ClassNotFoundException {
if (dimensions == 0) {
return null;
}
Object array = Array.newInstance(getArrayType(componentType, dimensions - 1), length);
for (int i = 0; i < length; i++) {
Array.set(array, i, createArray(componentType, dimensions - 1, length));
}
return array;
}
public static void main(String[] args) throws ClassNotFoundException {
Object object = createArray(Integer.class, 3, 10);
System.out.println(object.getClass());
}
}
诀窍是使用给定的组件类型为 N 维数组构造一个类。如果我们知道类名是如何存储在最低级别的,我们就可以做到这一点。其余代码只是一个简单无趣的递归。