Zoot101
Zoot101

Reputation: 51

Accessing an outer anonymous class's field from an inner anonymous class

To access the field x of an outer class A from an inner class B, I realize that you can use "A.this.x". But what if the outer class is also anonymous? For example,

public class Main1 {
    public static void main(String[] args) {
        Comparable c1 = new Comparable(){
            int x = 3;
            public int compareTo(Object o) {
                Comparable c2 = new Comparable(){
                    int x = 4;
                    public int compareTo(Object o) {
                        return x;  // <-- THIS LINE
                    }
                };
                return c2.compareTo(o);
            }
        };
        System.out.println(c1.compareTo(null));
    }
}

When this code is run, the value of 4 is printed because that is the value of c2's field x. However, I would like to change the line marked "THIS LINE" so that it returns the outer class's x (that is, c1's field x, with the value 3). If the outer class (that is, c1's class) were a named class A, then I could replace

return x;

with

return A.this.x;

But since the outer class is also anonymous, I don't have a name to use.

Question: Is there a way to modify the line labeled "THIS LINE" so that it refers to c1's field x rather than c2's, without changing the anonymous classes into named classes?

I realize this code is really ugly and it is not good programming style to use anonymous classes this way, but the code is being generated by another program, and this is the easiest way to implement the generator.

Upvotes: 5

Views: 2208

Answers (5)

Steven Huwig
Steven Huwig

Reputation: 20794

I believe you will have to declare the fields final -- the code you have there compiles only because of the shadowing you are complaining about. Not true.

This looks like a classic case where something like Lisp's gensym will make things easier. In other words, have the code generator use different identifiers for those variables -- e.g. x1 and x2.

Upvotes: 0

Boris Pavlović
Boris Pavlović

Reputation: 64642

Classes are anonymous -- nameless. No way of accessing their fields using name reference. There's no name.

Upvotes: 1

tddmonkey
tddmonkey

Reputation: 21184

AFAIK there's no way to achieve what you want. If you can change the code (as you appear to be able to) but don't want to change them into named classes, can you just change the name of the variables so you don't have scope issues? You should rename them for clarity anyway

Upvotes: 1

matt b
matt b

Reputation: 140011

The simple answer is to not shadow the variables:

public static void main(String[] args) {
    Comparable c1 = new Comparable() {
        int x = 3;
        public int compareTo(Object o) {
            Comparable c2 = new Comparable() {
                //changed this name
                int y = 4;
                public int compareTo(Object o) {
                    return x;
                }
            };
            return c2.compareTo(o);
        }
    };
    System.out.println(c1.compareTo(null));
}

Output:

3

Given that you are working with generated code, is this an option for you?

Upvotes: 2

Tim Frey
Tim Frey

Reputation: 9941

I would avoid hiding the other variable by choosing a name other than x.

Upvotes: 4

Related Questions