繁体   English   中英

使用整数进行模棱两可的方法调用

[英]Ambiguous method call with Integer

我正在Android中编写一些Junit测试,如果执行此操作:

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

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

模棱两可的方法调用:AssertEquals(int,int)和AssertEquals(Object,Object)都匹配

但是如果我这样做:

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的参数类型为int ,则不会编译

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

引入自动装箱和自动拆箱后,对于现有代码而言,继续以与以前完全相同的方式工作非常重要。 因此,当编译器决定调用哪个方法时,它首先仅考虑不需要自动装箱或自动拆箱的适用方法。 仅当没有此类方法时,编译器才会考虑需要自动装箱和/或自动拆箱的方法。

由于getId返回Integer ,因此在第一个参数也是Integer的情况下,可以调用ObjectObject方法而无需自动装箱。 但是,只能通过自动拆箱第二个参数来调用intint方法。 因此,在第二个示例中,在第一遍选择了ObjectObject重载。

在第一个示例中,您尝试传递一个int和一个Integer intint方法仅通过对第二个参数自动装箱而适用,而ObjectObject方法仅通过对第一个参数自动装箱而适用。 因此,无法在第一遍选择重载,并且由于这两种方法都不比另一种更具体(您需要查看最后一点),因此编译器无法在这两种方法之间进行选择。

重载解析非常复杂,实际上我已经对其进行了相当多的简化(也有涉及var-args的规则)。 但是实际上,您不需要学习所有这些规则-如果需要告诉编译器采用哪种方法,您可以始终包含一个或多个显式强制转换:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM