Search code examples
javareflectioncastingoverloadingprimitive

How to tell if a primitive type was cast into an object in Java?


In Java, consider the following piece of code:

int myPrimitiveInt = 5;
Integer myObjectInt = 4;

Object fromPrimitive = myPrimitiveInt;
Object fromObject = myObjectInt;

System.out.println(fromPrimitive.getClass());
System.out.println(fromObject.getClass());
System.out.println(int.class);

And the output:

class java.lang.Integer
class java.lang.Integer
int

What I would like, is a way to also get the output int for the first println.


WHY?, you will ask. Well, for one thing, I would just like to know if something like this is even possible.

But the actual practical reason behind this is an abstraction layer for testing private methods with primitive type arguments via reflection. The minimal code:

package testing;

import java.lang.reflect.Method;

public class Testing {
    private static void doStuff(int a) {
        System.out.println("primitive: " + ((Object) a).getClass());
    }

    public static void main(String[] args) throws ReflectiveOperationException {
        Reflect.reflect(Testing.class, "doStuff", 10);
    }
}

abstract class Reflect {
    static Object reflect(Class<?> clazz, String methodName, Object arg) throws ReflectiveOperationException {
        Method method = clazz.getDeclaredMethod(methodName, arg.getClass());
        method.setAccessible(true);
        return method.invoke(null, arg);
    }
}

The output:

Exception in thread "main" java.lang.NoSuchMethodException: testing.Testing.doStuff(java.lang.Integer)
at java.lang.Class.getDeclaredMethod(Class.java:2130)
at testing.Reflect.reflect(Testing.java:17)
at testing.Testing.main(Testing.java:11)

Expected output:

primitive: class java.lang.Integer

Or even better (if possible at all):

primitive: int

Note: I know I can do clazz.getDeclaredMethod(methodName, int.class). The whole point of this post is to make this procedure more abstract. Please do not give me answers suggesting to pass the argument types to the reflect method!


Solution

  • What happens when you write Object x = 10

    The int is autoboxed, which makes it into an Integer with value 10.

    Why can't this be detected afterwards

    Because there is no difference between the Integer with value 10 that was autoboxed and another Integer with value 10

    How can I get around this

    You need to add separate methods to overload for primitive values, these can handle the primitive values, so they do not get autoboxed.