3

Is there a way to access an anonymous outer class? A normal class can be accessed by ClassName.this. This doesn't work, as an anonymous class obviously doesn't have a name. I also tried using the extended class/interface (like Runnable.this) but it doesn't seem like it would work this way.

I'm sure this may be not the best coding style, I'm just curious if it's possible without storing this of the outer in a variable.

Example, watch out for outer.this:

public class A
{
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        synchronized (outher.this) {
                            outher.this.notify();
                        }
                    }
                }).start();
                try {
                    synchronized (this) {
                        wait();
                    }
                } catch (final InterruptedException ex) {}
            }
        }).start();
    }
}

2 Answers 2

2

No, there is no way to access anonymous classes from anywhere, except from inside them (i.e. otherwise than by this reference). Or by an explicitly declared variable.

final Runnable r1 = new Runnable() {...};
Runnable r2 = new Runnable() {
    public void run() {
         synchronized(r1) {...}
    }
};
Sign up to request clarification or add additional context in comments.

3 Comments

do you think it will work with synchronized (this.getClass().getEnclosingClass() ) with anonymous classes ?
@Eric R. I think that would do something different than what DiddiZ posted (maybe what you propose is what DiddiZ really wants). Assume the main method was being executed simultaneously in many different threads. In DiddiZ's code, they would all be syncronizing on different objects - thus no conflict. In your code, they would all be syncronizing on the same object, so there would be some conflict. But I suspect your code is what DiddiZ really wants.
This is synchronized by class, not by instance. If change synchronization monitors to synchronized (this.getClass().getEnclosingClass() ) and synchronized(this.getClass()) (instead of synchronized(this)) this will work. But if you run several threads on the same Runnable instances it will be like a static synchronized - i.e. across all instances.
1

You could add a method to return this middle this. It would be in scope but not hidden (is that the right term? Shadowed? I forget.).

public static void main(String[] args) {
    new Thread(new Runnable() {
        Runnable middleThis() { return this; } // <-- this
        @Override
        public void run() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (middleThis()) {
                        middleThis().notify();

Note, although anonymous inner classes have no name, they still are types. So adding members is visible to the immediate expression (new X() { Y z; }.z) and inside. You can't do middleThis().middleThis().

1 Comment

This is a clever way to get around the "without storing in a variable" restriction.

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.