我想更好地了解包含类的实例字段对匿名内部类(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?)的链接:“因此,静态上下文中的匿名类与静态嵌套类大致等效,因为它不保留对封闭类的引用,即使从技术上讲它不是静态类。”。
答案 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中的匿名内部类静态化?):“因此,静态上下文中的匿名类与静态嵌套类大致等效,因为它不保留对以下内容的引用:封闭类,即使从技术上讲它不是静态类。”。