3

I was testing the following code, and I was wondering how come the threads could access the the increment method?

I was thinking this since thread1 and thread2 are objects created from an anonymous class that don't inherit worker class how can they access the increment() method? what is the theory behind it?

public class Worker {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public void run() {
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                for(int i = 0; i < 10000; i++) {
                    increment();
                }
            }
        });
        thread1.start();

        Thread thread2 = new Thread(new Runnable() {
            public void run() {
                for(int i = 0; i < 10000; i++) {
                    increment();
                }
            }
        });
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("Count is: " + count);
    }
}
1
  • 4
    Anonymous classes have a reference to their enclosing class. Commented Sep 26, 2013 at 17:08

5 Answers 5

4

Since the Runnables are non-static inner classes , the Worker.this is implicitly inherited into the Runnable instances. So that what is really happening is

public void run(){
   Worker.this.increment();
}

If the class were static this wouldn't be the case.

Sign up to request clarification or add additional context in comments.

Comments

3

The Java Language Specification (JLS) states this about Inner Classes and Enclosing Instances

Inner classes include local (§14.3), anonymous (§15.9.5) and non-static member classes (§8.5).

and about Inner Classes and Enclosing Instances

An inner class C is a direct inner class of a class O if O is the immediately lexically enclosing class of C and the declaration of C does not occur in a static context.

and finally about Qualified this

Any lexically enclosing instance (§8.1.3) can be referred to by explicitly qualifying the keyword this.

Let C be the class denoted by ClassName. Let n be an integer such that C is the n'th lexically enclosing class of the class in which the qualified this expression appears.

The value of an expression of the form ClassName.this is the n'th lexically enclosing instance of this.

That's why you can access members of Worker.

The call

new Runnable()

within a Worker instance method, creates an inner class for Worker. So Worker is the 0'th lexically enclosing class of that Runnable. With regards to the JLS quotes above, replace ClassName with Worker and you have access to your method

Worker.this.increment()

It's done implicitly by the compiler

Comments

1

An anonymous inner class has access to the enclosing class instance fields and methods. In short, every instance of the inner class keeps a reference to the enclosing class precisely so that it is able to access its fields. If you want more info about inner classes, static classes, etc... check out the Java Tutorials on that topic (Nested Classes) at: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html Also, make sure to understand the dangers associated with non-static inner classes, as they can be troublesome and create memory leaks if you hand out references to the inner instance to code outside of the enclosing class.

Comments

0

Because it's a non-static inner class, it captures a reference to the Worker instance it is created within. That means you can invoke methods of the worker inside the anonymous class.

Comments

0

The "theory" is described in inner classes. The practice is, inner class constructors have hidden parameter which refers to outer class instance, and that parameter is saved in a hidden field. This field can be accessed with Worker.this construct from inner class methods.

2 Comments

this means that anonymous classes are always treated as inner classe?
yes, JLS clearly states that Inner classes include local, anonymous and non-static member classes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.