我正在查看从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