Question

Here is a utility method I have:

public static Class<?>[] getTypes(Object[] objects){
    Class<?>[] types = new Class<?>[objects.length];

    for (int i = 0; i < objects.length; i++) {
        types[i] = objects[i].getClass();
    }

    return types;
}

And here is a test case that fails:

@Test
public void getTypesTest() {
    Object[] objects = {"String", new StringBuilder(), new Integer(5), 5};

    Class<?>[] classes = ReflectionUtils.getTypes(objects);
    assertTrue(classes[0].equals(String.class));
    assertTrue(classes[1].equals(StringBuilder.class));
    assertTrue(classes[2].equals(Integer.class));
    assertTrue(classes[3].equals(int.class)); // Fails here
}

I realize that when I pass 5 within Object[], this is Boxed to new Integer(5).

How can I get the behavior I am expecting?

Edit

What I am expecting: The assertion that fails in my test will pass. What should I do with the method under test to achieve that?:

Was it helpful?

Solution

You cannot treat a primitive as an object as this is what defines a primitive as different to an object. By having an array of objects, you are ensuring everything in it is an object, not a primitive.


An int is not an object so you can't put it in an Object[] so the compiler will generate code to auto-box you value of 5. i.e. it calls Integer.valueOf(5) which is more efficient than new Integer(5) but is still an object.

You can't call .equals() on a primitive so the fact this compiles tells you its not.

BTW you can use int.class to get the class of int.

How can I get the behavior I am expecting?

Can you say exactly what you are expecting in English?


For those interested, the code for Integer.valueOf(int) in Java 6 and 7

public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

OTHER TIPS

The reason why it fails is that you have an array of object. A value of primitive type int gets auto-boxed as Integer and so the array contains an instance of Integer at the 3rd position. You can make the test pass by replacing

assertTrue(classes[3].equals(int.class)); // Fails here

with

assertTrue(classes[3].equals(Integer.class));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top