在匿名 class 覆盖中引入新变量

Introducing new variable in anonymous class override

关于匿名 class 实施,我没有遇到任何特殊问题,但我在玩弄时注意到一些让我觉得很有趣的东西。假设我有以下 class:

public class Foo {
    public void foo() {
        System.out.println("foo");
    } // foo
} // Foo

在主要 class 中,我有以下内容:

public class Main {
    
    public final Foo foo;
    
    public static void main(String[] args) {
        foo = new Foo() {
            
            public String test = "test";
            
            @Override
            public void foo() {
                super.foo();
                test = test + test;
                System.out.println(test);
            } // foo
        
        } // anonymous override

        // following line throws exception
        // System.out.println(foo.test);

        for (int i = 0; i < 3; i++) {
            foo.foo();
        } // for   
    } // main    

以下是输出到控制台的内容:

foo
test

foo
testtest

foo
testtesttesttest

无论我做什么,都无法从匿名覆盖之外访问 String test。即使我删除了“test = test + test”这一行并将测试声明为静态和最终的,它仍然无法从匿名实现的外部访问。

在这种情况下,我并没有特别需要使用变量,但这让我很好奇我是否遗漏了什么。只是,如果我需要将一个新变量嵌入到覆盖中,就像我在上面的示例中所做的那样。有什么方法可以让我从匿名覆盖外部访问变量“test”,而无需在“parent”中使用抽象方法或变量class?

有一个 class Foo 的匿名扩展实例(foo 指向的实例)。因此对一个实例的更改是累积的也就不足为奇了。

变量foo是对Foo的引用,而Foo没有test成员,所以没有什么可引用的。

您不能为确实有 test 成员的 class 编写演员表,因为它没有您可以说出的名字。

你可能会通过思考到达那里。

这一切看起来完全符合 class 层次结构的预期。 匿名子class只是一个没有名字的子class可以出现在源代码中。

如果您确实需要访问 test 则声明一个命名子class 而不是匿名子。合适的访问修饰符选择可以使您声明foo,例如作为 FooBar foo 如果 subclass 被称为 FooBar.