使用整数进行模棱两可的方法调用 [英] Ambiguous method call with Integer

查看:88
本文介绍了使用整数进行模棱两可的方法调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用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的情况下,可以在不进行自动装箱的情况下调用ObjectObject方法.但是,只能通过将第二个参数自动拆箱来调用intint方法.因此,在第二个示例中,在第一遍中选择了ObjectObject重载.

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.

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆