Java 带有整数的不明确方法调用
我正在用Android编写一些Junit测试,如果我这样做:Java 带有整数的不明确方法调用,java,android,junit,ambiguous,Java,Android,Junit,Ambiguous,我正在用Android编写一些Junit测试,如果我这样做: public void testSetId(){ Friend friend = new Friend(5); assertEquals(5,friend.getId()); } public void testSetId(){ Integer ID = 5; Friend friend = new Friend(ID); assertEquals(ID, friend.getId()); }
public void testSetId(){
Friend friend = new Friend(5);
assertEquals(5,friend.getId());
}
public void testSetId(){
Integer ID = 5;
Friend friend = new Friend(ID);
assertEquals(ID, friend.getId());
}
我得到一个不明确的方法调用错误
不明确的方法调用:
AssertEquals(int,int)和
AssertEquals(对象,对象)匹配
但如果我这样做:
public void testSetId(){
Friend friend = new Friend(5);
assertEquals(5,friend.getId());
}
public void testSetId(){
Integer ID = 5;
Friend friend = new Friend(ID);
assertEquals(ID, friend.getId());
}
它起作用了。我觉得第二个函数应该做完全相同的事情
这是怎么回事?在Java 5之前,没有自动装箱或自动取消装箱。这意味着如果一个方法
foo
有一个类型为Integer
的参数,那么下面的代码不会编译
foo(5); // 5 needs to be autoboxed
bar(new Integer(5)); // The Integer needs to be unboxed
类似地,如果一个方法bar
有一个类型为int
的参数,那么它不会编译
foo(5); // 5 needs to be autoboxed
bar(new Integer(5)); // The Integer needs to be unboxed
当引入自动装箱和自动取消装箱时,现有代码必须以与以前完全相同的方式继续工作。因此,当编译器决定调用哪个方法时,它首先只考虑不需要自动装箱或自动取消装箱的适用方法。只有当没有这样的方法时,编译器才会考虑需要自动装箱和/或自动解压的方法。
由于getId
返回一个整数
,因此当第一个参数也是整数
时,可以调用对象
,对象
方法而无需自动装箱。但是,int
,int
方法只能通过自动取消绑定第二个参数来调用。因此,在第二个示例中,在第一次通过时选择了对象
,对象
重载
在第一个示例中,您试图传递一个int
和一个整数。int
,int
方法仅通过自动取消装箱第二个参数应用,而对象
,对象
方法仅通过自动装箱第一个参数应用。因此,重载不能在第一次传递时选择,并且因为两个方法都比另一个方法更具体(您需要查找最后一位),编译器不能在这两个方法之间进行选择
重载解析非常复杂,实际上我已经将其简化了很多(还有涉及var args的规则)。但是在实践中,您不需要学习所有这些规则-如果您需要告诉编译器要应用哪种方法,您可以始终包含一个或多个显式强制转换:
assertEquals((Integer) id, friend.getId());
在Java5之前,没有自动装箱或自动取消装箱。这意味着如果一个方法foo
有一个类型为Integer
的参数,那么下面的代码不会编译
foo(5); // 5 needs to be autoboxed
bar(new Integer(5)); // The Integer needs to be unboxed
类似地,如果一个方法bar
有一个类型为int
的参数,那么它不会编译
foo(5); // 5 needs to be autoboxed
bar(new Integer(5)); // The Integer needs to be unboxed
当引入自动装箱和自动取消装箱时,现有代码必须以与以前完全相同的方式继续工作。因此,当编译器决定调用哪个方法时,它首先只考虑不需要自动装箱或自动取消装箱的适用方法。只有当没有这样的方法时,编译器才会考虑需要自动装箱和/或自动解压的方法。
由于getId
返回一个整数
,因此当第一个参数也是整数
时,可以调用对象
,对象
方法而无需自动装箱。但是,int
,int
方法只能通过自动取消绑定第二个参数来调用。因此,在第二个示例中,在第一次通过时选择了对象
,对象
重载
在第一个示例中,您试图传递一个int
和一个整数。int
,int
方法仅通过自动取消装箱第二个参数应用,而对象
,对象
方法仅通过自动装箱第一个参数应用。因此,重载不能在第一次传递时选择,并且因为两个方法都比另一个方法更具体(您需要查找最后一位),编译器不能在这两个方法之间进行选择
重载解析非常复杂,实际上我已经将其简化了很多(还有涉及var args的规则)。但是在实践中,您不需要学习所有这些规则-如果您需要告诉编译器要应用哪种方法,您可以始终包含一个或多个显式强制转换:
assertEquals((Integer) id, friend.getId());
您是否已将Friend
的id
定义为int
或Integer
?id是整数可以确认getId()的返回类型不是Integer int吗?是的,getId()的返回类型是整数您是否已将Friend
的id
定义为int
或Integer
?id是整数您是否可以确认getId()的返回类型是Integer而不是int?是的,getId()的返回类型是Integer