0

这是我拥有的实用方法:

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;
}

这是一个失败的测试用例:

@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
}

我意识到,当我通过5内部时Object[],这是 Boxed tonew Integer(5)

我怎样才能得到我期望的行为?

编辑

我的期望:在我的测试中失败的断言将通过。我应该如何使用被测方法来实现这一目标?:

4

2 回答 2

3

您不能将原语视为对象,因为这是将原语定义为与对象不同的原因。通过拥有一个对象数组,您可以确保其中的所有内容都是对象,而不是原始对象。


Anint不是对象,因此您不能将其放入 an 中,Object[]因此编译器将生成代码以自动将您的值设置为 5。即它调用Integer.valueOf(5)比对象更有效new Integer(5)但仍然是对象。

你不能调用.equals()一个原语,所以这个编译的事实告诉你它不是。

顺便说一句,您可以使用int.class来获取int.

我怎样才能得到我期望的行为?

你能用英语准确地说出你的期望吗?


对于那些感兴趣的人,Java 6 和 7 中 Integer.valueOf(int) 的代码

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);
}
于 2012-08-11T07:04:20.180 回答
0

它失败的原因是你有一个对象数组。原始类型的值int自动装箱Integer因此数组Integer在第三个位置包含一个实例。您可以通过替换使测试通过

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

assertTrue(classes[3].equals(Integer.class));
于 2012-08-11T09:00:45.387 回答