Java 语言基础
Android 开发基础
- Android 源码编译
- Android 开发基础知识
- AndroidManifest.xml
- Android 工程相关文件说明
- Android NDK 开发基础
- Android 基于监听的事件处理机制
- Android Handler 消息传递机制
- Android 基于回调的事件处理机制
Android 安全概述
Android 应用安全
- Android Application Security
- OWASP Mobile top 10_2014
- Android Activity Security
- Android Broadcast Security
- Android Content Provider Security
- Android Logcat Security
- Android Service Security
Android 逆向基础
Android 系统安全
Android 调试工具
- Smali Instrumentation
- Ida Pro
- Android Hook(上)
- Android Hook(下)
- Android Hook 框架(Cydia 篇)
- Android Hook 框架(XPosed 篇)
- Android Java 层的 Anti Hook 技巧
- Android 应用程序通用脱壳方法研究
- Android ART 运行时(上)
- Android ART 运行时(下)
- 初识 JEBAPI
- 常见 App 加固厂商脱壳方法
- Android Hook 技术防范漫谈
- Android Native Hook 技术线路概述
- Android Native Hook 工具实践
- Android Inline Hook 的指令修复详解
Java synthetic
synthetic的概念
According to the JVM Spec: "A class member that does not appear in the source code must be marked using a Synthetic attribute." Also, "The Synthetic attribute was introduced in JDK release 1.1 to support nested classes and interfaces."
I know that nested classes are sometimes implemented using synthetic fields and synthetic contructors, e.g. an inner class may use a synthetic field to save a reference to its outer class instance, and it may generate a synthetic contructor to set that field correctly. I'm not sure if it Java still uses synthetic constructors or methods for this, but I'm pretty sure I did see them used in the past. I don't know why they might need synthetic classes here. On the other hand, something like RMI or java.lang.reflect.Proxy should probably create synthetic classes, since those classes don't actually appear in source code. I just ran a test where Proxy did not create a synthetic instance, but I believe that's probably a bug.
Hmm, we discussed this some time ago back here. It seems like Sun is just ignoring this synthetic attribute, for classes at least, and we should too.
synthetic 实例
有synthetic标记的field 和method 是class 内部使用的,正常的源代码里不会出现synthetic field。
下面的例子是最常见的synthetic field
class parent {
public void foo() {
}
class inner {
inner() {
foo();
}
}
}
非static的inner class里面都会有一个this$0
的字段保存它的父对象。编译后的inner class 就像下面这样:
class parent$inner
{
synthetic parent this$0;
parent$inner(parent this$0)
{
this.this$0 = this$0;
this$0.foo();
}
}
所有父对象的非私有成员都通过 this$0
来访问,多层嵌套的情形如下所示。
public class Outer { // this$0
public class FirstInner { // this$1
public class SecondInner { // this$2
public class ThirdInner {
}
}
}
}
还有许多用到synthetic 的地方,比如使用了assert 关键字的class会有一个 synthetic static boolean $assertionsDisabled
字段,assert condition;
在class里被编译成:
if(!$assertionsDisabled && !condition)
{
throw new AssertionError();
}
在jvm 里所有class的私有成员都不允许在其他类里访问,包括它的inner class。在java语言里inner class是可以访问父类的私有成员的,在class里是用如下的方法实现的:
class parent
{
private int value = 0;
synthetic static int access$000(parent obj)
{
return value;
}
}
在inner class里通过access$000
来访问value字段。
另外一个例子,外包类访问嵌套类私有属性。
import java.lang.String;
public class A{
private static class B{
private String b1="b111";
private String b2="b2222";
}
public static void main(String[] args){
A.B b=new A.B();
String tmp=b.b1;
String tmp1=b.b2;
}
}
运行javap -private A.B 输出如下:
class A$B {
private java.lang.String b1;
private java.lang.String b2;
private A$B();
A$B(A$1);
static java.lang.String access$100(A$B);
static java.lang.String access$200(A$B);
}
生成了两个synthetic方法,分别对应于String tmp=b.b1;String tmp1=b.b2;访问两个私有属性。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论