2017-10-19 53 views
0

我在Android的写一些JUnit测试,如果我这样做:暧昧方法调用与整数

public void testSetId(){ 
    Friend friend = new Friend(5); 
    assertEquals(5,friend.getId()); 
} 

我得到一个模棱两可的方法调用错误。

暧昧的方法调用: 两者的assertEquals(INT,INT)和 的assertEquals(对象,对象)相匹配

但如果我这样做:

public void testSetId(){ 
    Integer ID = 5; 
    Friend friend = new Friend(ID); 
    assertEquals(ID, friend.getId()); 
} 

它的工作原理。我觉得第二个功能应该完成同样的事情。

这是怎么回事?

+1

是否定义了'id' Friend是int还是Integer? – GriffeyDog

+0

ID是一个整数 – user2782067

+0

您可以确认getId()的返回类型是Integer而不是int吗? –

回答

2

在Java 5之前,没有自动装箱或自动拆箱。这意味着,如果fooInteger类型的参数的方法,下面没有编译

foo(5); // 5 needs to be autoboxed 

同样,如果barint类型的参数的方法,这并不能编译

bar(new Integer(5)); // The Integer needs to be unboxed 

当引入自动装箱和自动拆箱时,现有代码必须继续以与以前完全相同的方式工作。因此,当编译器决定调用哪个方法时,它首先只考虑不需要自动装箱或自动拆箱的适用方法。只有在没有这样的方法时,编译器才会考虑需要自动装箱和/或自动拆箱的方法。

getId由于返回一个Integer,所述ObjectObject方法可以在不情况下自动装箱当第一个参数也是Integer被调用。但是只能通过自动拆箱第二个参数来调用int,int方法。因此在第二个例子中,第一遍选择了Object,Object过载。

在第一个示例中,您尝试通过intIntegerint,int方法仅适用于自动拆箱第二个参数,而Object,Object方法仅适用于自动装箱第一个参数。因此,在第一遍中不能选择重载,并且因为两种方法都不比其他方法更具体(您需要查看最后一页),编译器无法在两种方法之间进行选择。

重载解析是非常复杂的,我实际上已经简化了一下(还有涉及var-args的规则)。然而在实践中,你并不需要了解所有这些规则 - 如果有的话,你需要告诉要应用的方法,你总可以显式转换或铸编译:

assertEquals((Integer) id, friend.getId());