Java Surprise 1: Overloading and Inner Classes

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?