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

JavaArraysGwtInstanceof

Java Problem Overview


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?

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

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.

Java Solutions


Solution 1 - Java

You can use 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 toString method.

Solution 2 - Java

You can use instanceof.

JLS 15.20.2 Type Comparison Operator instanceof

> RelationalExpression: > RelationalExpression instanceof ReferenceType > > At run time, the result of the instanceof operator is true if the value of the RelationalExpression is not null and the reference could be cast to the ReferenceType without raising a ClassCastException. Otherwise the result is false.

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.

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

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

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.Arrays is very repetitive), but that's the way it is in Java with arrays.

See also

Solution 3 - Java

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.

Solution 4 - Java

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.

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

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

Specifically, it doesn't work if obj is 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.)

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

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

  • 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 instanceof expressions.

     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) == '[';
     }
    

1 - More precisely, the Class.isArray method is listed as supported by GWT in this page.

Solution 5 - Java

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

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

Solution 6 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionedbrasView Question on Stackoverflow
Solution 1 - JavaSteve KuoView Answer on Stackoverflow
Solution 2 - JavapolygenelubricantsView Answer on Stackoverflow
Solution 3 - Javauser1928596View Answer on Stackoverflow
Solution 4 - JavaStephen CView Answer on Stackoverflow
Solution 5 - JavaLucas PiresView Answer on Stackoverflow
Solution 6 - JavaSina MadaniView Answer on Stackoverflow