111

如果一个对象是一个不使用反射的数组,我如何在 Java 中查看?以及如何在不使用反射的情况下遍历所有项目?

我使用 Google GWT,所以我不允许使用反射 :(

我很想在不使用反射的情况下实现以下方法:

private boolean isArray(final Object obj) {
  //??..
}

private String toString(final Object arrayObject) {
  //??..
}

顺便说一句:我也不想使用 JavaScript 以便在非 GWT 环境中使用它。

4

6 回答 6

280

您可以使用Class.isArray()

public static boolean isArray(Object obj)
{
    return obj!=null && obj.getClass().isArray();
}

这适用于对象和原始类型数组。

对于 toString 看看Arrays.toString. 您必须检查数组类型并调用适当的toString方法。

于 2010-04-27T23:26:30.137 回答
73

您可以使用instanceof.

JLS 15.20.2 类型比较运算符instanceof

 RelationalExpression:
    RelationalExpression instanceof ReferenceType

在运行时,instanceof运算符的结果是true如果RelationalExpression的值不是null,并且可以将引用强制转换为ReferenceType而无需引发 a ClassCastException。否则结果为false

这意味着您可以执行以下操作:

Object o = new int[] { 1,2 };
System.out.println(o instanceof int[]); // prints "true"        

如果要检测所有数组类型,则必须检查对象是否为instanceof boolean[], byte[], short[], char[], int[], long[], float[], double[], 或。Object[]

此外, anint[][]是 an instanceof Object[],因此取决于您要如何处理嵌套数组,它可能会变得复杂。

对于toString,java.util.Arrays有 atoString(int[])和其他你可以使用的重载。它也deepToString(Object[])适用于嵌套数组。

public String toString(Object arr) {
   if (arr instanceof int[]) {
      return Arrays.toString((int[]) arr);
   } else //...
}

这将是非常重复的(但甚至java.util.Arrays是非常重复的),但这就是在 Java 中使用数组的方式。

也可以看看

于 2010-04-27T22:15:15.293 回答
39

可以使用以下代码分别访问数组的每个元素:

Object o=...;
if ( o.getClass().isArray() ) {
    for(int i=0; i<Array.getLength(o); i++){
        System.out.println(Array.get(o, i));
    }
}

请注意,没有必要知道它是哪种底层数组,因为这适用于任何数组。

于 2014-05-09T15:25:58.727 回答
10

原始类型的数组之间或原始类型的数组和引用类型的数组之间没有子类型关系。见JLS 4.10.3

因此,以下作为测试是否是任何类型obj的数组是不正确的:

// INCORRECT!
public boolean isArray(final Object obj) {
    return obj instanceof Object[];
}

obj具体来说,如果是一维基元数组,它就不起作用。(它确实适用于具有更高维度的原始数组,因为所有数组类型都是 的子类型Object。但在这种情况下它没有实际意义。)

我使用 Google GWT,所以我不允许使用反射 :(

最好的解决方案(isArray问题的数组部分)取决于什么算作“使用反射”。

  • 在 GWT 中,调用obj.getClass().isArray()不计入使用反射1,因此这是最好的解决方案。

  • 否则,确定对象是否具有数组类型的最佳方法是使用instanceof表达式序列。

    public boolean isArray(final Object obj) {
        return obj instanceof Object[] || obj instanceof boolean[] ||
           obj instanceof byte[] || obj instanceof short[] ||
           obj instanceof char[] || obj instanceof int[] ||
           obj instanceof long[] || obj instanceof float[] ||
           obj instanceof double[];
    }
    
  • 您也可以尝试如下弄乱对象类的名称,但调用obj.getClass()与反射接壤。

    public boolean isArray(final Object obj) {
        return obj.getClass().toString().charAt(0) == '[';
    }
    

1 - 更准确地说,该方法在此页面Class.isArray中列为 GWT 支持的方法。

于 2010-04-27T22:46:00.363 回答
0

简单obj instanceof Object[](在 JShell 上测试)。

于 2019-11-24T15:24:13.023 回答
0

您可以创建一个实用程序类来检查该类是否代表任何CollectionMapArray

  public static boolean isCollection(Class<?> rawPropertyType) {
        return Collection.class.isAssignableFrom(rawPropertyType) || 
               Map.class.isAssignableFrom(rawPropertyType) || 
               rawPropertyType.isArray();
 }
于 2019-01-22T19:24:36.840 回答