Search code examples
javavariablesoverridinganonymous-class

Introducing new variable in anonymous class override


I'm not facing any particular problem regarding anonymous class implementation, but I noticed something while toying around that strikes me as quite interesting. Let's say I have the following class:

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

and in a main class, I have the following:

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    

The following is what's printed out to the console:

foo
test

foo
testtest

foo
testtesttesttest

The String test cannot be accessed from outside of the anonymous override, no matter what I do. Even when I erase the line "test = test + test" and declare test as static and final, it is still inaccessible from outside of the anonymous implementation.

I have no particular need for using a variable in this kind of situation, but it makes me curious if there's something that I'm missing here. Just, WHAT IF I needed to embed a new variable into an override just like I did above in the example. Is there any way that I could possibly access the variable "test" from outside of the anonymous override without using an abstract method or variables in the "parent" class?


Solution

  • There's one instance of anonymous extension of class Foo (the instance that foo points to). so it should not be surprising that changes to the one instance are cumulative.

    The variable foo is a reference to a Foo, and a Foo does not have a test member, so there's nothing to reference.

    You can't write a cast to the class that does have atest member, since it does not have a name you can utter.

    You could probably get there with reflection.

    This all seems exactly as expected with class hierarchies. An anonymous subclass is just a subclass without a name that can appear in source code.

    If you actually need access to test then declare a named subclass instead of an anonymous one. Suitable choice of access modifiers will allow you to declare foo suitably, e.g. as FooBar foo if the subclass is called FooBar.