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?:
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);
}