[英]NoClassDefFoundError on Non-static class with private constructor
[英]Does an anonymous class that implements a private abstract static class hold a reference to its enclosing class, when created in a non-static context?
我在 Effective Java,第 3 版中讀到,在非靜態上下文中創建的匿名類包含對其封閉 class 的不可見引用。 對於正在實現內部 static class 的匿名 class 也是如此,但在非靜態 ZC1C42145268E683984DZ 中創建但在非靜態 ZC1C42145268E683984D
例如:
class Concept {
public Response func() {
return new Inner {
@Override
protected Object bar() {
return new Object;
}
}.invoke();
}
private abstract static Inner {
protected Response invoke() {
return Response.status(SC_OK).entity(bar).build();
}
protected abstract Object Response bar();
}
}
在 func() 方法中創建的匿名 class 是否包含對其封閉 class 概念的引用?
根據JLS §15.9.5 :
匿名 class 始終是內部 class (§8.1.3); 它絕不是 static(§8.1.1,§8.5.1)。
請注意,對於匿名 class 擴展static
class 的情況,JLS 中沒有例外。
因此,它應該具有對其封閉 class 的實例的引用。
我簡化了您的示例,將其轉換為合法的自包含 Java class,編譯它並使用javap -c
查看匿名 class 的字節碼。 構造函數代碼確實引用了封閉的class並將其保存在隱藏字段( this$0
)中。
class Concept {
public Inner func() {
return new Inner() {
@Override
protected Object bar() {
return new Object();
}
};
}
private abstract static class Inner {
protected abstract Object bar();
}
}
javap -c 'Concept$1.class'
Compiled from "Concept.java"
class Concept$1 extends Concept$Inner {
final Concept this$0;
Concept$1(Concept);
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:LConcept;
5: aload_0
6: invokespecial #2 // Method Concept$Inner."<init>":()V
9: return
protected java.lang.Object bar();
Code:
0: new #3 // class java/lang/Object
3: dup
4: invokespecial #4 // Method java/lang/Object."<init>":()V
7: areturn
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.