简体   繁体   中英

Can Anonymous inner class instantiated within a static method has access to instance members of containing class?

I want to understand better the visibility of instance fields of containing class to an Anonymous inner class (AIC) .

There have been lots of talks that AIC has an implicit reference to the containing class' instance ( When exactly is it leak safe to use (anonymous) inner classes? ). With that logic, even when an AIC is instantiated within a static method, it should have access to the instance fields of the containing class. But I can't find a way to test this as the compiler gives errors.

For eg, in the below code, I get: "Non-static field 's' can't be referred from a static context" by the compiler when I refer 's' within print() method of the AIC:

public interface TestInterface {
    void print();
}


public class AICTest {
    public String s = "something";
    public static void main( String[] args ) {

        new TestInterface() {
            @Override
            public void print() {
                System.out.println( s ); **<-- compilation error**
            }
        }.print();

    }
}

Could you suggest if it's possible for the AIC instance to access 's' in the above example?

Edit/Answer I want to clarify that I am aware that static methods have access to class members and instance methods have access to instance & class members. The confusion was more about the general statement that AIC always have an implicit reference to containing class' object. This clearly is not the case for AIC initialised within a static method. @shmosel shared a link which answers my question ( Is it possible to make anonymous inner classes in Java static? ): "So an anonymous class in a static context is roughly equivalent to a static nested class in that it does not keep a reference to the enclosing class, even though it's technically not a static class.".

You have to have an instance of AICTest to read 's' out of, since 's' is an instance variable. Here's an example that will work, representing your example modified to access an existing AICTest object that could potentially come from anywhere:

class AICTest {
    public String s = "something";
    public static void main( String[] args ) {

        AICTest aic = new AICTest();

        new TestInterface() {
            @Override
            public void print() {
                System.out.println(aic.s);
            }
        }.print();

    }
}

To be clear, running 'main' does not create an instance of AICTest. You have to do a 'new' somewhere to create an instance of AICTest.

Another option is to make 's' static. Then it isn't associated with any particular AICTest object, and so it exists even if you haven't instantiated an AICTest object:

class AICTest {
    public static String s = "something";
    public static void main( String[] args ) {

        new TestInterface() {
            @Override
            public void print() {
                System.out.println(s);
            }
        }.print();

    }
}

As you can see, I haven't added any visibility modifiers. So your idea about visibility was sound. If it otherwise makes sense to access 's', the visibility is there in your code. The problem here has nothing to do with visibility.

This may not be what you want, but you can:

interface TestInterface {
    void print();
}
class AICTest {
    public String s="something";
    public static void main(String[] args) {
        AICTest aicTest=new AICTest();
        new TestInterface() {
            @Override public void print() {
                System.out.println(aicTest.s);
            }
        }.print();
    }
}

The confusion was more about the general philosophy that AIC always have an implicit reference to containing class' object. This clearly is not the case for AIC initialised within a static method. @shmosel shared a link which answers my question (Is it possible to make anonymous inner classes in Java static?): "So an anonymous class in a static context is roughly equivalent to a static nested class in that it does not keep a reference to the enclosing class, even though it's technically not a static class.".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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