“静态合成”是什么意思?
我正在查看一些从 Java 字节码获得的反汇编代码。我看到一些声明如下:
.method static synthetic access$0()Lcom/package/Sample;
我无法弄清楚 synthetic
或 access$0
的含义。有人可以帮我理解这部分吗?
I am looking at some disassembled code obtained from Java bytecode. I see some declaration as follows:
.method static synthetic access$0()Lcom/package/Sample;
I am not able to figure out what the synthetic
or access$0
mean. Can someone please help me understand this part?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在java语言中,内部类可以访问其封闭类的私有成员。然而,在Java字节码中,不存在内部类的概念,并且私有成员是不可访问的。为了解决这个问题,编译器在外部类中创建合成访问器方法。我相信这就是您在这里看到的。
access$0
只是方法的名称。我不确定synthetic
会做什么。它可能只是对其他编译器隐藏该方法以确保封装。In the java language, inner classes can access private members of their enclosing class. However, in Java bytecode, the concept of inner classes does not exist, and the private members are not accessible. To work around this, the compiler creates synthetic accessor methods in the outer class. I believe that is what you are seeing here.
access$0
is simply the name of the method. I'm not sure what, if anything thesynthetic
does. It may just hide the method from other compilers to ensure encapsulation.合成字段,(2)
另请参阅
JavaTM 虚拟机规范 ( §4.7.6)
或 Java 中的综合类。Synthetic field, (2)
See also
The JavaTM Virtual Machine Specification (§4.7.6)
or Synthetic Class in Java.assert
语句 JDK 1.8 案例研究assert
语句是在 Oracle 中生成静态合成
字段的构造示例JDK 1.8.0_45:基本上编译为:
这可以通过以下方式验证:
其中包含:
生成合成字段,以便 Java 在加载时只需要调用
Assert.class.desiredAssertionStatus()
一次,并且然后它将结果缓存在那里。另请参阅:https://stackoverflow.com/a/29439538/895245 了解更详细的说明。
请注意,此合成字段可能会与我们可能定义的其他字段产生名称冲突。例如,以下内容无法在 Oracle JDK 1.8.0_45 上编译:
唯一“阻止”的就是在标识符上不使用美元的命名约定。另请参阅:何时应使用美元符号($) 在变量名中?
额外奖励:
会起作用,因为与 Java 不同,字节码允许多个具有相同名称但不同类型的字段:名称相同但类型不同的变量
assert
statement JDK 1.8 case studyThe
assert
statement is an example of construct that generates astatic synthetic
field in Oracle JDK 1.8.0_45:basically compiles to:
This can be verified with:
which contains:
The synthetic field is generated so that Java only needs to call
Assert.class.desiredAssertionStatus()
once at load time, and it then caches the result there.See also: https://stackoverflow.com/a/29439538/895245 for a more detailed explanation.
Note that this synthetic field can generate name conflicts with other fields we may define. E.g., the following fails to compile on Oracle JDK 1.8.0_45:
The only thing that "prevents" that is the naming convention of not using dollars on your identifiers. See also: When should I use the dollar symbol ($) in a variable name?
Bonus:
would work, because unlike Java, the bytecode allows multiple fields with the same name but different types: Variables having same name but different type