After another look I see that I created a completely new test case. That
overridden in Y.
Jikes 1.22 javac 1.5 and 1.6 all accept the code. I guess my surprise was
was warranted, albeit completely unrelated to the original post.
Sorry for the red herring.
On Thu, 14 Dec 2006, Mike Schilling wrote:
No. The runtime would throw an exception if the method being called
(X:speak(Y y)) weren't found. Since it is found, no exception is generated.
Would it be correct for a compiler to
accept the earlier case that javac rejects?
No. The JLS is quite clear here: the compile-time check is based on the
declared type of the object.
.
This is the part I found odd (at first blush). I did not do a good job of
reposting the code from the original question but in the source that javac
rejected Y *does* have the required method-- it inherits it from X. The
compiler rejects this. If you override the method (even just to call
super.speak(y)) the compiler allows it. It seems like with the information
available at compile time the same issue exists even with the method
explicitly placed in the subclass. Could the compiler reject both?
public class Test{
public static void main(String[] args){
Y y=new Y();
y.speak(y);
}
}
class X{
void speak(Y y){
System.out.println("X");
}
}
class Y extends X{
void speak(X x){
System.out.println("Y");
}
//toggle this override on/off with comments
void speak(Y y)
{
super.speak(this);
}
}
I guess I do see the difference somewhat, but I am still left wondering-- if
the compiler is allowed to choose the narrower method in the latter case, why
is it disallowed this in the first case? Either way it gets bound to the
narrower method type.