Java 如何在不使用反射的情况下查看对象是否为数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2725533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 12:09:49  来源:igfitidea点击:

How to see if an object is an array without using reflection?

javaarraysgwtinstanceof

提问by edbras

How can I see in Java if an Object is an array without using reflection? And how can I iterate through all items without using reflection?

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

I use Google GWT so I am not allowed to use reflection :(

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

I would love to implement the following methods without using refelection:

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

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

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

BTW: neither do I want to use JavaScript such that I can use it in non-GWT environments.

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

采纳答案by Steve Kuo

You can use Class.isArray()

您可以使用 Class.isArray()

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

This works for both object and primitive type arrays.

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

For toString take a look at Arrays.toString. You'll have to check the array type and call the appropriate toStringmethod.

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

回答by polygenelubricants

You can use instanceof.

您可以使用instanceof.

JLS 15.20.2 Type Comparison Operator instanceof

JLS 15.20.2 类型比较运算符 instanceof

 RelationalExpression:
    RelationalExpression instanceof ReferenceType

At run time, the result of the instanceofoperator is trueif the value of the RelationalExpressionis not nulland the reference could be cast to the ReferenceTypewithout raising a ClassCastException. Otherwise the result is false.

 RelationalExpression:
    RelationalExpression instanceof ReferenceType

在运行时,instanceof运算符的结果是RelationalExpressiontrue的值是否不是,并且可以将引用强制转换为ReferenceType而不引发. 否则结果是。nullClassCastExceptionfalse

That means you can do something like this:

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

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

You'd have to check if the object is an instanceof boolean[], byte[], short[], char[], int[], long[], float[], double[], or Object[], if you want to detect all array types.

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

Also, an int[][]is an instanceof Object[], so depending on how you want to handle nested arrays, it can get complicated.

此外, anint[][]是 an instanceof Object[],因此根据您希望如何处理嵌套数组,它可能会变得复杂。

For the toString, java.util.Arrayshas a toString(int[])and other overloads you can use. It also has deepToString(Object[])for nested arrays.

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

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

It's going to be very repetitive (but even java.util.Arraysis very repetitive), but that's the way it is in Java with arrays.

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

See also

也可以看看

回答by Stephen C

There is no subtyping relationship between arrays of primitive type, or between an array of a primitive type and array of a reference type. See JLS 4.10.3.

原始类型的数组之间,或者原始类型的数组和引用类型的数组之间没有子类型关系。请参阅JLS 4.10.3

Therefore, the following is incorrect as a test to see if objis an array of any kind:

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

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

Specifically, it doesn't work if objis 1-D array of primitives. (It does work for primitive arrays with higher dimensions though, because all array types are subtypes of Object. But it is moot in this case.)

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

I use Google GWT so I am not allowed to use reflection :(

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

The best solution (to the isArrayarray part of the question) depends on what counts as "using reflection".

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

  • In GWT, calling obj.getClass().isArray()does not count as using reflection1, so that is the best solution.

  • Otherwise, the best way of figuring out whether an object has an array type is to use a sequence of instanceofexpressions.

    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[];
    }
    
  • You could also try messing around with the name of the object's class as follows, but the call to obj.getClass()is bordering on reflection.

    public boolean isArray(final Object obj) {
        return obj.getClass().toString().charAt(0) == '[';
    }
    
  • 在 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 - More precisely, the Class.isArraymethod is listed as supported by GWT in this page.

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

回答by user1928596

One can access each element of an array separately using the following code:

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

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

Notice that it is unnecessary to know what kind of underlying array it is, as this will work for any array.

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

回答by Lucas Pires

You can create a utility class to check if the class represents any Collection, Mapor Array

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

  public static boolean isCollection(Class<?> rawPropertyType) {
        return Collection.class.isAssignableFrom(rawPropertyType) || 
               Map.class.isAssignableFrom(rawPropertyType) || 
               rawPropertyType.isArray();
 }

回答by Sina Madani

Simply obj instanceof Object[](tested on JShell).

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