Logo Questions Linux Laravel Mysql Ubuntu Git Menu

Resolving static method ambiguity

I have been working on understanding java compilation and I have come across a question. Say we have a class set up like this

public class Ambiguity 
    static class G
        void A()
            System.out.println("Regular Method");

    static class b
        static void A()
            System.out.println("Static Method");

    public static void main(String[] args)

        G b = new G();

How does the compiler know weather to call the method static void A() in the class b or the regular method void A() on the object b of type G. Based on tests I ran it appears to call the object b (of type G) method but I did not know if this is always standard procedure. In this situation how could the static method be called.

like image 884
popgalop Avatar asked Mar 16 '23 23:03


2 Answers

  • The local variable, named b and of type G,
  • "obscures" the name of the type b anywhere where the variable b is in scope.
  • The method on the type b is therefore not called.

The obscuring occurs as the local scoped variable is more specific. The rules for obscuring are complex, but summarised in 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.

Obscuring like this is bad practice and should be avoided. However you can work around the ambiguity in this case by providing a qualified name (§6.2) for the type. This changes the applicable name selection rule from §6.5:

G b = new G();
Ambiguity.b.A(); // calls Ambiguity.b.A()
b.A();           // calls Ambiguity.G.A() on variable b


Static Method
Regular Method


Specifically, the unqualified name b in this context is classified initially as an Ambiguous Name (§6.5.1). It is then reclassified by the priority rule from §6.5.2 (bold is my highlighting, italics is my addition):

If the AmbiguousName is a simple name, consisting of a single Identifier

• If the Identifier appears within the scope (§6.3) of a local variable declaration (§14.4) or parameter declaration (§8.4.1, §8.8.1, §14.20) or field declaration (§8.3) with that name, then the AmbiguousName is reclassified as an ExpressionName (... as opposed to a TypeName, from the lower priority rule 3).

like image 160
Andy Brown Avatar answered Mar 29 '23 01:03

Andy Brown

The "best match" will be called. Objects are more precise than static methods, and as such object methods will be used by default; you can call a static method via Class.Method();. What's actually wrong here is that your local variable b happens to have the same name as the class, and as such, it is hiding the class.

You can still call the class static method if you use the full path: Ambiguity.b.A();

like image 43
Aify Avatar answered Mar 28 '23 23:03