我正在查看從Java字節碼中獲得的一些反彙編代碼。我看到一些聲明如下:「靜態合成」是什麼意思?
.method static synthetic access$0()Lcom/package/Sample;
我無法弄清楚什麼synthetic
或access$0
意思。有人能幫我理解這個部分嗎?
我正在查看從Java字節碼中獲得的一些反彙編代碼。我看到一些聲明如下:「靜態合成」是什麼意思?
.method static synthetic access$0()Lcom/package/Sample;
我無法弄清楚什麼synthetic
或access$0
意思。有人能幫我理解這個部分嗎?
甲編譯器創建的字段的本地內部類鏈接到一個塊的局部變量或引用類型參數。
又見The JavaTM Virtual Machine Specification (§4.7.6)
或Synthetic Class in Java。
在java語言中,內部類可以訪問其封閉類的私有成員。但是,在Java字節碼中,內部類的概念不存在,並且私有成員不可訪問。要解決此問題,編譯器會在外部類中創建綜合訪問器方法。我相信這就是你在這裏看到的。 access$0
只是方法的名稱。我不確定synthetic
會做什麼。它可能只是隱藏其他編譯器的方法來確保封裝。
在Oracle JDK 1.8.0_45斷言是產生static synthetic
字段的一個示例:
public class Assert {
public static void main(String[] args) {
assert System.currentTimeMillis() == 0L;
}
}
基本上編譯爲:
javac Assert.java
javap -c -constants -private -verbose Assert.class
:
public class Assert {
// This method is synthetic.
static final boolean $assertionsDisabled =
!Assert.class.desiredAssertionStatus();
public static void main(String[] args) {
if (!$assertionsDisabled) {
if (System.currentTimeMillis() != 0L) {
throw new AssertionError();
}
}
}
}
這可以與被驗證
其中包含:
static final boolean $assertionsDisabled;
descriptor: Z
flags: ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
合成字段使得爪哇只需要在加載時調用一次Assert.class.desiredAssertionStatus()
產生,然後將其高速緩存其結果存在。
參見:https://stackoverflow.com/a/29439538/895245了更詳細的解釋。
注意,這個合成領域可以產生命名衝突,我們可以定義等多個領域。例如,下面的編譯失敗在Oracle JDK 1.8.0_45:
public class Assert {
static final boolean $assertionsDisabled = false;
public static void main(String[] args) {
assert System.currentTimeMillis() == 0L;
}
}
唯一令「防止」,即不使用美元,對你的標識符的命名規則。另請參見:When should I use the dollar symbol ($) in a variable name?
獎勵:
static final int $assertionsDisabled = 0;
會的工作,因爲不像Java的字節碼可以使用相同的名稱,但不同類型的多個領域:Variables having same name but different type
我不能相信這是不自然! – Mehrdad 2011-03-07 17:57:20