9

How can the static inner class M and static member M [of class C] share the same name?

The following code generates "White" as output:

public class Amazed{

    public static void main(String[] args) {
        System.out.println(B.M.W);
    }
}

class B {
    public static class M {       
        static String W = "Black";
    }

    static C M = new C();
}

class C {
    String W = "White";
}

how the member object is accessed and not the static class member : W ["Black"]

if i want to access the member within static class M how to do that?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Dineshkumar
  • 4,165
  • 5
  • 29
  • 43

4 Answers4

2

Chapter 6 of the Java Language Specification (especially Section 6.5) spells out the gruesome details of how Java sorts out what a particular identifier means in a particular context. The rules are fairly complex, but, roughly speaking, Java has six name spaces:

  • Package names
  • type names
  • field (variable) names
  • method names
  • local variable names (including parameters)
  • labels

The same identifier can be used for entities in each of these name spaces. Note that type (class) names and field names live separately, which explains why your code is legal.

Inherited names in the same name space can also sometimes be shadowed or masked. Sometimes an identifier is ambiguous; it then needs to be qualified in some way (e.g., with a package name) or the compiler will complain.

Code obfuscators use this to great advantage, to the point where you can end up with a package named a.a and a class named a in package a (which also would be identified as a.a). Not to mention that Java key words like do and for are legal names in .class files (but not in Java source). It helps make reverse engineering a real bear.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
1

The variable obscures the type of the same name. If a name could be interpreted to be either a variable or a type, the variable is preferred.

You can avoid this by not giving them the same name.

From the Java Language Specification, section 6.4.2: Obscuring:

6.4.2. Obscuring

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.

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
0

In your particular case where M can be instantiated you could use the fact that statics can be accessed in a non-static way:

public class Amazed{
   @SuppressWarnings("static-access")
   public static void main(String[] args) {
       B.M val = new B.M();
       System.out.println(val.W);
   }
}

class B {
   public static class M {       
       static String W = "Black";
   }

   static C M = new C();
}

class C {
   String W = "White";
}

The above will print 'Black' because you disambiguated the identifier by referring to it through an instance of B.M. By no means is this a good idea in production code, of course, since static fields should not be accessed in a non-static way. Likewise, it requires you to create an instance of B.M.

cyon
  • 9,340
  • 4
  • 22
  • 26
0

After everyone's help and little play i found that even without creating object for inner class we can access the member W "Black".

simply using this statement

M.W

But i can't figure out access level. [because its public?] even without public it worked. how's that?

Dineshkumar
  • 4,165
  • 5
  • 29
  • 43