How to see if an object is an array without using reflection?
JavaArraysGwtInstanceofJava 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).