1

Single dimension primitive array doesn't work correctly on generic method. new int[] should be passed as T[] instead of T. Thanks to isArray(), I'm able to differentiate an array, but having issue when try to execute Arrays.deepToString(). How to cast generic object as primitive array?

/* Output
println(T $obj)
1
println(T[] $obj)
[1]
println(T[] $obj)
[[1]]
println(T[] $obj)
[[[1]]]
println(T $obj)
1
println(T $obj)
Exception in thread "main" java.lang.ClassCastException: [I cannot be cast to [Ljava.lang.Object;
    at Test.doSomething(Test.java:21)
    at Test.main(Test.java:12)
Java Result: 1
*/

import java.util.Arrays;

public class Test {

    public static void main(String[] args) throws Exception {
        doSomething((Integer) 1);
        doSomething(new Integer[]{1});
        doSomething(new Integer[][]{{1}});
        doSomething(new Integer[][][]{{{1}}});

        doSomething((int) 1);
        doSomething(new int[]{1}); //java.lang.ClassCastException
        doSomething(new int[][]{{1}});
        doSomething(new int[][][]{{{1}}});
    }

    public static <T> void doSomething(T $obj) {
        System.out.println("println(T $obj)");

        if ($obj.getClass().isArray()) {
            System.out.println(Arrays.deepToString((T[]) $obj)); //java.lang.ClassCastException
        } else {
            System.out.println($obj);
        }
    }

    public static <T> void doSomething(T[] $obj) {
        System.out.println("println(T[] $obj)");

        if ($obj.getClass().isArray()) {
            System.out.println(Arrays.deepToString($obj));
        } else {
            System.out.println($obj);
        }
    }
}
2
  • You can't use Java generics with the primitive types (at least without boxing to the corresponding wrapper type). And for that, you'd need something like public static <T> void doSomething(T[] $obj) or the varargs version like public static <T> void doSomething(T... $obj) Commented Feb 25, 2016 at 3:00
  • Using a switch on Class<T>.getComponentType() should do it. Commented Feb 29, 2016 at 0:26

1 Answer 1

1

You can't. Arrays.deepToString() takes parameter Object[], which an array-of-primitives type is not a subtype of. If you know you have an array of primitives, you can simply call Arrays.toString() on it (since arrays of primitives cannot be "deep"), which is overloaded for all array-of-primitives types.

The only other case is that you have something which might be an array of primitives, or an array of references, and you don't know which, and if it's an array of references, you want to print it deeply recursively. You could write your own method that manually checks the type of the object against each array-of-primitives type, and if it is, cast it to the right type and call Arrays.toString() on it, and if it is an array of references, cast it to Object[] and call Arrays.deepToString() on it.

Or, if you are lazy, you can just wrap whatever in one additional layer of array, and do Arrays.deepToString() on that:

Arrays.deepToString(new Object[]{$obj})

and then just strip out the extra set of brackets afterwards.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.