可以在静态方法中实例化的匿名内部类访问包含类的实例成员吗?

时间:2019-03-26 00:01:33

标签: java

我想更好地了解包含类的实例字段对匿名内部类(AIC)的可见性。

有很多讨论说AIC对包含类的实例(When exactly is it leak safe to use (anonymous) inner classes?)有隐式引用。使用这种逻辑,即使在静态方法中实例化AIC时,它也应有权访问包含类的实例字段。但是由于编译器出错,我找不到测试方法。

例如,在下面的代码中,我得到:当我在打印中引用“ s”时,编译器“无法从静态上下文引用非静态字段“ s”” ()的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();

    }
}

您能否建议上面的示例中AIC实例是否可以访问“ s”?

编辑/回答 我想澄清一下,我知道静态方法可以访问类成员,而实例方法可以访问实例和类成员。混乱更多地是关于一般性的陈述,即AIC总是隐含引用包含类的对象。在静态方法中初始化AIC显然不是这种情况。 @shmosel共享了一个回答我的问题(Is it possible to make anonymous inner classes in Java static?)的链接:“因此,静态上下文中的匿名类与静态嵌套类大致等效,因为它不保留对封闭类的引用,即使从技术上讲它不是静态类。”。

3 个答案:

答案 0 :(得分:0)

您必须具有AICTest实例才能从中读取“ s”,因为“ s”是实例变量。这是一个有效的示例,表示您对示例进行了修改以访问可能来自任何地方的现有AICTest对象:

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

    }
}

很明显,运行“ main”不会创建AICTest的实例。您必须在某处进行“新操作”才能创建AICTest实例。

另一个选择是使's'为静态。然后,它不与任何特定的AICTest对象相关联,因此即使您尚未实例化AICTest对象,它也存在:

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

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

    }
}

如您所见,我尚未添加任何可见性修饰符。因此,您关于可见度的想法是合理的。如果访问“ s”在其他情况下有意义,则代码中存在可见性。这里的问题与可见性无关。

答案 1 :(得分:0)

这可能不是您想要的,但是您可以:

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

答案 2 :(得分:0)

更多的困惑是关于AIC总是隐式引用包含类对象的一般哲学。在静态方法中初始化AIC显然不是这种情况。 @shmosel共享了一个链接,该链接回答了我的问题(是否可以使Java中的匿名内部类静态化?):“因此,静态上下文中的匿名类与静态嵌套类大致等效,因为它不保留对以下内容的引用:封闭类,即使从技术上讲它不是静态类。”。