As some of you might know, I'm working on implementing components of a Java compiler in Stratego. Obviously, I have to study the Java Language Specification in great detail for that. I had the impression that I knew a lot a about the Java language, but I still learn a lot of new details. Some of these details are funny, some are not. I've already encountered a lot of these causes and I'll try to blog about them from now.
My first post in this series is about this fragment:
class Foo { void f(String s) {} class Bar { void f(int x) {} class Fred { void g() { f("aaa"); } } } }
Did you know that you cannot overload the method f
in this way?
The reason for this is that the specification separates method invocation in a few phases. The first compile-time phases determines the class to search for the method to invoke. For a plain method invocation (just and identifier), the JLS specifies that the class to search for methods is the innermost type declaration that has a method of that name. In this case, this will be the class Bar
. Hence, the later phases that handle method overloading will not consider the method f
that takes a String argument.
I don't think I've encountered this issue during my Java programming. Did you?
1 comment:
Not in Java, but in C++ -- the Java rule mirrors how C++ does it. First, a "nearest" scope containing the name is located. Then, overloading is considered within that scope.
Stroustrup has a decent explanation of this, though its presence in a C++ FAQ is a clue that it trips up some people sometimes.
Post a Comment