Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Anonymous class variables

Tags:

java

I was experimenting with anonymous classes today. When I do System.out.println(super.x);, it prints 12, and when I use System.out.println(x); it prints 4. I thought super.x would print 4 and was wondering if someone could please explain to me why this is?

public class AnonClass {

    private int x = 1;

    public AnonClass(int x) {
        this.x = x;
    }

    public static void main(String[] args) {
        AnonClass test = new AnonClass(4);
        test.testMethod();
    }

    public void testMethod() {

        AnonClass anon = new AnonClass(12) {
            {
                System.out.println(super.x); //Prints 12
                System.out.println(x); //prints 4
            }
        };

    }
}
like image 266
Rubiks Avatar asked Oct 11 '16 20:10

Rubiks


People also ask

What are anonymous classes?

A nested class that doesn't have any name is known as an anonymous class. An anonymous class must be defined inside another class. Hence, it is also known as an anonymous inner class. Its syntax is: class outerClass { // defining anonymous class object1 = new Type(parameterList) { // body of the anonymous class }; }

What variables can an anonymous inner class access?

An anonymous class has access to the members of its enclosing class. An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final.

What's meant by anonymous class explain with example?

An anonymous inner class can be useful when making an instance of an object with certain "extras" such as overloading methods of a class or interface, without having to actually subclass a class. In simple words, a class that has no name is known as an anonymous inner class in Java.

Can anonymous class be passed as a parameter?

Yes, by adding an initializer method that returns 'this', and immediately calling that method: int myVariable = 1; myButton. addActionListener(new ActionListener() { private int anonVar; public void actionPerformed(ActionEvent e) { // How would one access myVariable here? // It's now here: System.


2 Answers

When you define an anonymous class like this inside class AnonClass:

AnonClass anon =
    new AnonClass(12) {
      {
        System.out.println(super.x); //Prints 12
        System.out.println(x); //prints 4
      }
    };

the compiler will create a class something like this:

class AnonClass$1 extends AnonClass {
  final AnonClass enclosed;

  AnonClass$1(AnonClass enclosed, int x) {
    super(x);
    System.out.println(super.x);
    System.out.println(enclosed.x);
    this.enclosed = enclosed;
  }
}

and then invoke it like:

AnonClass anon = new AnonClass$1(this, 12);

Note that the invocation of the superconstructor (super(x);) happens before the contents of the instance initializer (the System.out.println lines).

As such, the field AnonClass.x is initialized to 12 by the superconstructor, and then its value is printed as 12 via System.out.println(super.x);.

Then, System.out.println(x) is actually referencing the x in the enclosing instance of AnonClass, whose value is 4.

The reason it doesn't print 12 again is that x is private; and as it says in JLS Sec 8.2:

Members of a class that are declared private are not inherited by subclasses of that class.

So there is no AnonClass$1.x to print; the only identifier in scope called x is AnonClass.x.

like image 120
Andy Turner Avatar answered Oct 26 '22 19:10

Andy Turner


You have two classes here: regular class AnonClass and anonymous class AnonClass$1 extending AnonClass

Both these classes have x field

You also have two objects: one of type AnonClass instantiated inside main method with x = 4 and second one of type AnonClass$1 instantiated inside testMethod() with x = 12

When you're printing the value of super.x you are accessing the x field of second object; but the value of x belongs to the first object cause you class is not static and contains an implicit reference to instance of outer class

Reference: Nested Classes in Java

like image 32
bedrin Avatar answered Oct 26 '22 18:10

bedrin