简体   繁体   English

从内部匿名类访问外部匿名类的字段

[英]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". 要从内部类B访问外部类A的字段x,我意识到您可以使用“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. 运行此代码时,将打印值4,因为这是c2的字段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). 但是,我想更改标记为“THIS LINE”的行,以便返回外部类的x(即c1的字段x,值为3)。 If the outer class (that is, c1's class) were a named class A, then I could replace 如果外部类(即c1的类)是一个命名的类A,那么我可以替换

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? 问题:有没有办法修改标记为“THIS LINE”的行,使其引用c1的字段x而不是c2,而不将匿名类更改为命名类?

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. 我意识到这段代码非常难看,以这种方式使用匿名类是不好的编程风格,但代码是由另一个程序生成的,这是实现生成器的最简单方法。

我会通过选择x以外的名称来避免隐藏其他变量。

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 3

Given that you are working with generated code, is this an option for you? 鉴于您正在使用生成的代码,这是一个选项吗?

AFAIK there's no way to achieve what you want. AFAIK没有办法实现你想要的。 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 无论如何,您应该重新命名它们

Classes are anonymous -- nameless. 类是匿名的 - 无名的。 No way of accessing their fields using name reference. 无法使用名称引用访问其字段。 There's no name. 没有名字。

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. 这看起来像一个典型的案例,像Lisp的gensym之类的东西会让事情变得更容易。 In other words, have the code generator use different identifiers for those variables -- eg x1 and x2. 换句话说,让代码生成器为这些变量使用不同的标识符 - 例如x1和x2。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM