The method is ambiguous for the type - why not solve it

public class Animal {} public class Bird extends Animal {} public class Mamal extends Animal {} public class Human extends Mamal {} public class Main { public void Hungry(Mamal mamal){ System.out.println("Mammal"); } public void Hungry(Human human){ System.out.println("Human"); } public void Hungry(Bird bird){ System.out.println("Bird"); } public static void main(String a[]){ Main main = new Main(); main.Hungry(null); } 

The compiler says that the Hungry (Mamal) method is ambiguous. I would expect to execute the Man method, since it is the lowest level. I could not find the reason for the ambiguity from http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12

+6
source share
3 answers

Human and Bird are on the same level of the inheritance hierarchy (but not visually). Or think of them as completely unrelated reference types. Therefore, one is no more specific than the other.

If you remove the Hungry(Bird) method, your code will be compiled.

The rules are more specific here .

One method of a fixed argument element with the name m is more specific than another method of a member with the same name and arity if all of the following conditions are true:

  • Declared parameter types of the first member method T1, ..., Tn.

  • The declared parameter types of another method are U1, ..., Un.

  • If the second method is general, then let R1 ... Rp (p ≥ 1) be of its type, let Bl be the declared boundary of Rl (1 ≤ l ≤ p), let A1 ... Ap be arguments of the type deduced (§15.12 .2.7) for this, the challenge is under the initial restrictions Ti <Ui (1 ≤ i ≤ n), and let Si = Ui [R1 = A1, ..., Rp = Ap] (1 ≤ i ≤ n).

  • Otherwise, let Si = Ui (1 ≤ i ≤ n).

  • For all j from 1 to n, Tj <: Sj.

  • If the second method is the general method described above, then Al <: Bl [R1 = A1, ..., Rp = Ap] (1 ≤ l ≤ p).

So you have

 public void Hungry(Human human){ System.out.println("Human"); } public void Hungry(Bird bird){ System.out.println("Bird"); } 

So, Human is T1 , and Bird is U1 (an attempt is also made to the contrary). Methods are not common.

 S1 = U1 

For all j from i to n (1 to 1) this should contain: Ti <: Si , where <: is

We write T <: S to indicate that the subtype relation holds between types T and S.

This is not true for our two methods, since Human not a subtype of Bird and vice versa, therefore there is no more specific method to call, i.e. ambiguity.

It is just as if you

 void method(String s){} void method(RandomReferenceType t) {} 

and tried to call

 method(null); 
+11
source

Since null has no type associated with it, the compiler does not know which of your hungry methods should be called; therefore it is "ambiguous." To fix it, just add it:

 public class Main { public void hungry(Mamal mamal){ System.out.println("Mammal"); } public void hungry(Human human){ System.out.println("Human"); } public void hungry(Bird bird){ System.out.println("Bird"); } public static void main(String a[]){ Main main = new Main(); main.hungry((Mamal)null); } } class Animal {} class Bird extends Animal {} class Mamal extends Animal {} class Human extends Mamal {} 
+2
source

The problem is that you have three methods with the same name and you pass a null value. The compiler does not know which method you are calling. Just write one i.e. public void hungry(Animal animal) and check the type of animal inside. For example, if(animal instanceof Bird) { System.out.println("Bird") .... Also change the method names to lowercase. Sometimes the compiler does not work.

+2
source

All Articles