-1

关于匿名类的实现,我没有遇到任何特别的问题,但是我在玩弄的时候注意到了一些让我觉得很有趣的东西。假设我有以下课程:

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

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

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 声明为静态和最终的,它仍然无法从匿名实现之外访问。

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

4

1 回答 1

1

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

该变量foo是对 a 的引用Foo,而 aFoo没有test成员,因此没有什么可引用的。

您不能为具有test成员的类编写强制转换,因为它没有您可以说出的名称。

您可能可以通过反思到达那里。

这一切似乎与类层次结构的预期完全一样。匿名子类只是一个没有名称的子类,可以出现在源代码中。

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

于 2021-09-01T23:06:48.853 回答