0

Somewhere in my code I have following function:

private static Object formatArg(Object arg)
{
    Object formatterArg;
    if (arg instanceof Collection)
        formatterArg = getFormatter().format((Collection) arg, mFormatters);
    else if (arg instanceof Object[])
        formatterArg = getFormatter().format((Object[]) arg, mFormatters);
    else
        formatterArg = getFormatter().format(arg, mFormatters, false);

    return formatterArg;
}

The problem is this arg instanceof Object[]. The goal of this is that I want to handle int[], long[] and any primitives arrays as well.

Question

Is it possible to find out of an Object is an array, no matter of which type and pass it to another function? This should work with arrays of primitive types as well as with an array of Objects... I can use arg != null && arg.getClass().isArray() to check it the Object is an array, but then I don't know how to pass it on (as I can't just cast and int[] to an Object[]...). Any tricks to achieve what I want?

Edit

A beautiful solution would automatically convert int[] to Integer[], long[] to Long[] and so on. Those converted arrays would work with my instanceof Object[], but this means I have to manually check for these primitive types, which I can do, but this is ugly. Any better ideas?

prom85
  • 16,896
  • 17
  • 122
  • 242
  • 1
    https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#isArray-- – JB Nizet Nov 30 '16 at 23:00
  • What type is returned by `getFormatter()`? – shmosel Nov 30 '16 at 23:03
  • int[] and other primitive types are not object array therefore typecasting in itself will fail. You will have to first convert them into Integer[] or Long[] – Acewin Nov 30 '16 at 23:03
  • I know that (I even use this function in my question!). But then I can't automatically cast an `int[]` to an `Integer[]` which I then could hand on to my formatter. Therefore, I would have to handle all primitive types one by one, which is not that hard, but I would like to avoid it and maybe someone knows a beautiful solution – prom85 Nov 30 '16 at 23:03
  • "as I can't just cast and int[] to an Object[]" -- seems like you need format specializations for primitive array `format(int[], ...)` and so on. – Victor Sorokin Nov 30 '16 at 23:04
  • true but you can easily read them. I will suggest this http://stackoverflow.com/questions/12361492/how-to-determine-the-primitive-type-of-a-primitive-variable. Because in the end wrapping will still work if u read the array elements one by one – Acewin Nov 30 '16 at 23:05
  • ... and JDK itself doesn't shy away from such lists of specializations, e.g., `ObjectOutputStream#writeArray`. – Victor Sorokin Nov 30 '16 at 23:06
  • I updated my question with an edit... I'm aware of the manual solution (converting primitive arrays to object arrays, element by element), but this looks ugly, so I wonder, if there is a more beautiful solution to this problem – prom85 Nov 30 '16 at 23:07

2 Answers2

1

A quick workout to get an object array

public static void main(String[] args) {
    int[] arrInt = {23, 45, 67, 89};
    long[] arrLong = {23, 45, 67, 89};
    System.out.println(convertarrObj(arrInt));
}

static Object[] convertarrObj(Object arrObj){
    if(arrObj.getClass().isArray()) {
        Object[] objArray = new Object[Array.getLength(arrObj)];
        for(int i = 0; i < Array.getLength(arrObj) ; i++) {
            objArray[i] = Array.get(arrObj, i);
        }
        return objArray;
    }

    return null;
}

And it can be easily made sure to return an array of Integer or Long or anyother type

static Object[] convertarrObj(Object arrObj){
    Object[] objArrayObjects = null;
    if(arrObj instanceof Collection)
        return null;
    else if(arrObj.getClass().isArray()) {
        Object firstElement = Array.get(arrObj, 0);
        if (firstElement instanceof Integer) {
            objArrayObjects = new Integer[Array.getLength(arrObj)];
        } else if(firstElement instanceof Long) {
            objArrayObjects = new Long[Array.getLength(arrObj)];
        }
        for(int i = 0; i < Array.getLength(arrObj) ; i++) {
            objArrayObjects[i] = Array.get(arrObj, i);
        }
    }

    return objArrayObjects;
}

Logic behind this is auto wrapping in Java between primitive datatype and corresponding class. Determine Type of Primitive data type

Community
  • 1
  • 1
Acewin
  • 1,657
  • 4
  • 17
  • 36
  • that looks exactly like what I was looking for, I'll try it – prom85 Nov 30 '16 at 23:16
  • @prom85, updated the second method I have added returns Integer Array or Long array. And to be correct you helped with getting the final logic. I am pretty sure you will be able to think of better logic and maybe avoid one iteration to read the elements of array. – Acewin Nov 30 '16 at 23:24
  • You forget to check the array for length == 0... But for my usecase, the first thing was exactly what I was looking for, a beautiful way to handle all primitive types at once... Alternatively, to avoid reflection, the `isArray` call can even be replaced with this: `if (arg instanceof boolean[] || arg instanceof byte[] || arg instanceof short[] || arg instanceof char[] || arg instanceof int[] || arg instanceof long[] || arg instanceof float[] || arg instanceof double[])`... – prom85 Nov 30 '16 at 23:29
  • I don't understand the need to create a new object when you just have to define `private static Object formatArg(int[] arg)` to specialize the behaviour. – SR_ Nov 30 '16 at 23:29
  • Yes maybe, but the idea is to pass object to convertarrObj and not know beforehand that it is an array. Also, this solution is just to give an approach to what OP needs rather being a perfect solution in its own. After reading OP's question I realized is pretty capable to clearly code to achieve what he needs and is just asking for a suitable direction rather than a perfect solution – Acewin Nov 30 '16 at 23:36
0

Yes, you can use:

arg.getClass().isArray()

Here's the associated Javadoc - you'll also find methods that help you determine the component type of the array, which is likely to be useful for your code as well.

BeeOnRope
  • 60,350
  • 16
  • 207
  • 386