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
intis not an object so you can’t put it in anObject[]so the compiler will generate code to auto-box you value of 5. i.e. it callsInteger.valueOf(5)which is more efficient thannew 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.classto get the class ofint.Can you say exactly what you are expecting in English?
For those interested, the code for Integer.valueOf(int) in Java 6 and 7