Amit,
Read the JLS 15.12.2.2 Choose the Most Specific Method explanation, here they have given a detailed explanation to go about chosing the most specific method.
The main points to be noted in the explanation are:
The informal intuition is that one method declaration is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error.
If there is exactly one maximally specific method, then it is in fact the most specific method; it is necessarily more specific than any other method that is applicable and accessible
Now here is the answer to ur question:
1) We invoke the method m(gfc213, gfc213)
2) Suppose we take up the method "static void m(GFC211 x, GFC213 y)...."
U can see that invocation handled by m(GFC211 x, GFC213 y) can also be passed to the methods:
:- m(GFC211 x, GFC212 y)
:- m(GFC211 x, GFC211 y)
without giving any compilation errors
3) Suppose we take up the method "static void m(GFC212 x, GFC212 y)..."
Again here we can see that invocation handled by m(GFC212 x, GFC212 y) can also be passed to the methods:
:- m(GFC212 x, GFC211 y)
:- m(GFC212 x, GFC211 y)
Now according to the first point i posted from JLS
The informal intuition is that one method declaration is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error.
According to the statement above, there are two most specifc methods,but we require only 1, so this results in compilation errors which says ambiguous methods
Now i change ur program a bit:
----------------------------------------------------
class GFC211 {} class GFC212 extends GFC211 {}
class GFC213 extends GFC212 {
static void m(GFC211 x, GFC211 y) {System.out.print("GFC211,GFC211");}
static void m(GFC211 x, GFC212 y) {System.out.print("GFC211,GFC212");}
static void m(GFC211 x, GFC213 y) {System.out.print("GFC211,GFC213");}
public static void main(String[] args) {
GFC213 gfc213 = new GFC213(); m(gfc213, gfc213);
}
--------------------------------------------------------
1) We invoke the method m(gfc213, gfc213)
2) Suppose we take up the method "static void m(GFC211 x, GFC213 y)...."
U can see that invocation handled by m(GFC211 x, GFC213 y) can also be passed to the methods:
:- m(GFC211 x, GFC212 y)
:- m(GFC211 x, GFC211 y)
without giving any compilation errors
3) Suppose we take up the method "static void m(GFC211 x, GFC212 y)..."
U can see that the invocation handled by m(GFC211 x, GFC212 y) cannot be passed to any other method
4) Suppose we take up the method "static void m(GFC211 x, GFC211 y..."
Again here also U can make out that the invocation handled by m(GFC211 x, GFC211 y) cannot be passed to any other method
So, from these points u can figure out that there is only one most specific method i.e. m(gfc213, gfc213) and so no compilation errors
I hope this makes u clear of ur doubt,
Anyone pelase let me know whether i am making sense or not, do tell me if at all i am wrong at any place
Thanks