有没有办法在没有强制转换的情况下解决Ambiguous方法调用?

时间:2017-08-21 14:13:16

标签: java generics intellij-idea overloading

初步问题

我有以下代码:

public static void main(String[] args) throws Exception {
    test(new LinkedList());
}

public static void test(Queue qeueue){
    System.out.println("Queue");
}

public static void test(List list){
    System.out.println("List");
}

InteliJ不允许我运行该项目。

  1. 有什么方法可以解决这个问题吗?
  2. 如果两者的特异性相同,JVM会使用哪两个?它是随机的吗?
  3. 我已阅读相关的SO q / a,但没有人给出如何编译它的答案。 他们只列出原因,例如Ambiguous method call intelliJ 15

    更新

    更令人讨厌的例子是:

    test(null);
    

    我一直在阅读非常有趣的文章:http://javabypatel.blogspot.be/2016/05/ambiguous-method-overloading.html

3 个答案:

答案 0 :(得分:2)

LinkedList ListDequeQueuetest

因此,Collection方法调用对于编译器来说是不明确的,因为无法确定要调用的重载。

合并方法以接受唯一对象(例如@model MessaggiVM <form role="form" class="form-inline" method="post" action="Messaggi/VaiAllaHome"> <button id="btnHome">Vai alla pagina iniziale</button> <div class="form-group"> <label for="nascondi">hiding</label> <input id="nascondi" type="checkbox" name="nascondi" value="true" /> </div> <input type="hidden" name="elencoPost" value="@Model.Posts" /> @*@Html.ActionLink("Messaggi", "VaiAllaHome", new { posts = Model.Posts} )*@ </form> ),或者显式地转换为目标类型(或者,具有不同的方法名称)。

还要记住:不鼓励使用原始类型,您可能希望参数化您的通用集合。

答案 1 :(得分:1)

使用方法重载,编译器决定使用哪种方法。对于JVM,您的两种方法完全不同,就好像它们的名称完全不同。使用方法覆盖,这是不同的,然后“点之前的对象”的运行时类决定,这就是JVM的工作。

因此,您必须处理编译器并帮助他选择正确的方法。编译器的静态类型分析必须明确排除两种情况之一。

在您的代码中,编译器会看到test(new LinkedList());并推导出一个静态类型的LinkedList。知道该类同时实现了ListQueue,他就无法选择一种方法。

你不想像test((List) new LinkedList());那样投射。那么您可能愿意接受的唯一变体就是引入一个明确类型的局部变量,例如

List arg = new LinkedList();
test(arg);

然后编译器不再知道LinkedList类型,但只有大约List,不能再看到运行时实例也是Queue并选择{{ 1}}方法。

但实际上,它也在施展。

当然,您可以(也许应该)通过为具有重叠参数类型的方法指定不同的名称来避免整个混乱。

答案 2 :(得分:0)

如你所说,不能没有施法。由于LinkedList实现了两个接口,因此编译器不会链接哪个接口,因此会产生不明确的调用错误。一旦你投射它,编译器就会知道意图并相应地链接一个调用。

相关问题