Is there a way to work around Ambiguous method call without casting?

痴心易碎 提交于 2019-12-25 08:47:20

问题


Initial Question

I have the following code:

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 is not letting me run the project.

  1. Is there any way to work around this issue?
  2. Which of the two would the JVM use if both are equal in specificity? Is it random?

I have read related SO q/a but no one gives an answer how to compile around it. They just list the reason, e.g. Ambiguous method call intelliJ 15

Update

An even more nasty example is:

test(null);

I have been reading the article that is quite interesting: http://javabypatel.blogspot.be/2016/05/ambiguous-method-overloading.html


回答1:


A LinkedList both a List and a Deque, which in turn is a Queue.

The test method invocation is therefore ambiguous to the compiler, as there is no way to figure which overload to invoke.

Either merge the methods to accept a unique object (e.g. a Collection), or explicitly cast to either target type (or, have different method names altogether).

Also remember: it is discouraged to use raw types, you probably want to parametrize your generic collections.




回答2:


With method overloading, it's the compiler who decides which method to use. To the JVM, your two methods are completely distinct, as if they had completely different names. With method overriding, that's different, then the run-time class of the "object before the dot" decides, and that's the JVM's job.

So, you have to deal with the compiler and help him to choose the correct method. The compiler's static type analysis must clearly exclude one of the two cases.

In your code, the compiler sees test(new LinkedList()); and deduces a static type of LinkedList. Knowing that that class implements both List and Queue, he can't select one method.

You don't want to cast like in test((List) new LinkedList());. Then the only variant that you might be willing to accept is to introduce a local variable of an unambiguous type, e.g.

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

Then the compiler no longer knows about the LinkedList type, but only about List, can no longer see that the run-time instance also is a Queue and selects the List method.

But effectively, it's casting as well.

And of course, you can (and maybe should) avoid the whole mess by giving different names to methods with overlapping parameter types.




回答3:


Not possible without casting as you said. Since LinkedList implements both interfaces, compiler does not which one to link and thus gives an ambiguous call error. Once you cast it, compiler gets to know the intention and links a call accordingly.



来源:https://stackoverflow.com/questions/45799302/is-there-a-way-to-work-around-ambiguous-method-call-without-casting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!