Search code examples
javavisibilityjava-7jls

How to fully qualify a class whose package name collides with a local member name?


OK, here's a very curious Java 7 language puzzle for the JLS specialists out there. The following piece of code won't compile, neither with javac nor with Eclipse:

package com.example;

public class X {
    public static X com = new X();

    public void x() {
        System.out.println(com.example.X.com);
        // cannot find symbol  ^^^^^^^
    }
}

It appears as though the member com completely prevents access to the com.* packages from within X. This isn't thoroughly applied, however. The following works, for instance:

public void x() {
    System.out.println(com.example.X.class);
}

My question(s):

  • How is this behaviour justified from the JLS?
  • How can I work around this issue

Note, this is just a simplification for a real problem in generated code, where full qualification of com.example.X is needed and the com member cannot be renamed.

Update: I think it may actually be a similar problem like this one: Why can't I "static import" an "equals" method in Java?


Solution

  • This is called obscuring (jls-6.4.2).

    A simple name may occur in contexts where it may potentially be interpreted as the name of a variable, a type, or a package. In these situations, the rules of §6.5 specify that a variable will be chosen in preference to a type, and that a type will be chosen in preference to a package. Thus, it is may sometimes be impossible to refer to a visible type or package declaration via its simple name. We say that such a declaration is obscured.