5

要从内部类 B 访问外部类 A 的字段 x,我意识到您可以使用“A.this.x”。但是如果外部类也是匿名的呢?例如,

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));
    }
}

运行此代码时,将打印 4 的值,因为这是 c2 的字段 x 的值。但是,我想更改标记为“THIS LINE”的行,使其返回外部类的 x(即 c1 的字段 x,值为 3)。如果外部类(即 c1 的类)是命名类 A,那么我可以替换

return x;

return A.this.x;

但是由于外部类也是匿名的,所以我没有名称可以使用。

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

我意识到这段代码真的很难看,这样使用匿名类也不是很好的编程风格,但是代码是由另一个程序生成的,这是实现生成器的最简单方法。

4

5 回答 5

4

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

于 2009-02-11T14:55:10.633 回答
2

简单的答案是不要隐藏变量:

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));
}

输出:

3

鉴于您正在使用生成的代码,这是否适合您?

于 2009-02-11T14:59:42.633 回答
1

AFAIK 没有办法实现你想要的。如果您可以更改代码(您似乎可以)但不想将它们更改为命名类,您可以只更改变量的名称,这样您就不会遇到范围问题吗?为了清楚起见,您应该重命名它们

于 2009-02-11T15:00:28.623 回答
1

类是匿名的——无名的。无法使用名称引用访问他们的字段。没有名字。

于 2009-02-11T15:00:54.050 回答
0

我相信您将不得不将这些字段声明为 final - 您那里的代码编译只是因为您抱怨的阴影。不对。

这看起来像是一个经典案例,Lisp 的gensym之类的东西会让事情变得更容易。换句话说,让代码生成器为这些变量使用不同的标识符——例如x1 和x2。

于 2009-02-11T14:57:13.623 回答