使用整数进行模棱两可的方法调用 [英] Ambiguous method call with Integer
问题描述
我正在用Android编写一些Junit测试,如果这样做的话:
I am writing some Junit tests in Android, and if i do this:
public void testSetId(){
Friend friend = new Friend(5);
assertEquals(5,friend.getId());
}
我收到一个模棱两可的方法调用错误.
I get an ambiguous method call error.
歧义方法调用: AssertEquals(int,int)和 AssertEquals(Object,Object)匹配
Ambiguous Method Call: Both AssertEquals(int, int) and AssertEquals(Object, Object) match
但是,如果我这样做:
public void testSetId(){
Integer ID = 5;
Friend friend = new Friend(ID);
assertEquals(ID, friend.getId());
}
有效.我觉得第二个功能应该做的完全一样.
It works. I feel like the second function should be doing the exact same thing.
这是怎么回事?
推荐答案
在Java 5之前,没有自动装箱或自动拆箱.这意味着,如果方法foo
具有类型为Integer
的参数,则以下内容不会编译
Before Java 5 there was no autoboxing or auto-unboxing. This meant that if a method foo
had a parameter of type Integer
, the following did not compile
foo(5); // 5 needs to be autoboxed
类似地,如果方法bar
具有类型为int
的参数,则不会编译
Similarly, if a method bar
had a parameter of type int
, this did not compile
bar(new Integer(5)); // The Integer needs to be unboxed
引入自动装箱和自动拆箱后,对于现有代码而言,继续以与以前完全相同的方式工作非常重要.因此,当编译器决定调用哪个方法时,它首先仅考虑不需要自动装箱或自动拆箱的适用方法.仅当没有此类方法时,编译器才会考虑需要自动装箱和/或自动拆箱的方法.
When autoboxing and auto-unboxing were introduced, it was essential for existing code to continue to work in exactly the same way as before. Therefore when the compiler decides which method is being called, it first considers only the applicable methods that do not require autoboxing or auto-unboxing. Only if there are no such methods does the compiler consider methods requiring autoboxing and/or auto-unboxing.
由于getId
返回Integer
,因此在第一个参数也是Integer
的情况下,可以在不进行自动装箱的情况下调用Object
,Object
方法.但是,只能通过将第二个参数自动拆箱来调用int
,int
方法.因此,在第二个示例中,在第一遍中选择了Object
,Object
重载.
Since getId
returns an Integer
, the Object
, Object
method can be called without autoboxing in the case when the first argument is also an Integer
. However the int
, int
method can only be called by auto-unboxing the second parameter. Therefore in your second example, the Object
, Object
overload is selected on the first pass.
在第一个示例中,您尝试传递int
和Integer
. int
,int
方法仅通过对第二个参数自动装箱而适用,而Object
,Object
方法仅通过对第一个参数自动装箱而适用.因此,无法在第一遍选择重载,并且由于这两种方法都不比另一种更具体(您需要查看最后一点),因此编译器无法在这两种方法之间进行选择.
In your first example, you are trying to pass an int
and an Integer
. The int
, int
method applies only by auto-unboxing the second argument, while the Object
, Object
method applies only by autoboxing the first argument. Therefore the overload cannot be chosen on the first pass, and because neither method is more specific than the other (you'll need to look that last bit up) the compiler cannot choose between the two methods.
重载解析非常复杂,实际上我已经对其进行了相当多的简化(也有涉及var-args的规则).但是在实践中,您不需要学习所有这些规则-如果需要告诉编译器采用哪种方法,您可以始终包含一个或多个显式强制转换:
Overload resolution is extremely complicated, and I've actually simplified it quite a bit (there are also rules involving var-args). However in practice, you don't need to learn all these rules - if ever you need to tell the compiler which method to apply you can always include an explicit cast or casts:
assertEquals((Integer) id, friend.getId());
这篇关于使用整数进行模棱两可的方法调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!