Java反射在JVM的实现
来源:互联网 发布:windows我的电脑图标 编辑:程序博客网 时间:2024/06/06 02:03
1. 什么是Java反射,有什么用?
调用一些私有方法,实现黑科技。比如双卡短信发送、设置状态栏颜色、自动挂电话等。
实现序列化与反序列化,比如PO的ORM,Json解析等。
实现跨平台兼容,比如JDK中的SocketImpl的实现
通过xml或注解,实现依赖注入(DI),注解处理,动态代理,单元测试等功能。比如Retrofit、Spring或者Dagger
2. Java Class文件的结构
typedef struct {
u4 magic;
/*0xCAFEBABE*/
u2 minor_version; /*网上有表可查*/
u2 major_version; /*网上有表可查*/
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-
1
];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
//重要
u2 fields_count;
field_info fields[fields_count];
//重要
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}ClassBlock;
常量池(constant pool):类似于C中的DATA段与BSS段,提供常量、字符串、方法名等值或者符号(可以看作偏移定值的指针)的存放
access_flags: 对Class的flag修饰
typedef
enum
{ ACC_PUBLIC =
0x0001
, ACC_FINAL =
0x0010
, ACC_SUPER =
0x0020
, ACC_INTERFACE =
0x0200
, ACC_ACSTRACT =
0x0400
}AccessFlag
this class/super class/interface: 一个长度为u2的指针,指向常量池中真正的地址,将在Link阶段进行符号解引。
filed: 字段信息,结构体如下
typedef struct fieldblock {
char
*name;
char
*type;
char
*signature;
u2 access_flags;
u2 constant; union { union {
char
data[
8
]; uintptr_t u;
long
long
l;
void
*p;
int
i;
} static_value;
u4 offset;
} u;
} FieldBlock;
method_info {
u2 access_flags;
u2 name_index;
//the parameters that the method takes and the
//value that it return
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
JVM文档
周志明的《深入理解Java虚拟机》,少见的国内精品书籍
一些国外教程的解析
3. Java Class加载的过程
第一步通过ClassLoader进行读取、连结操作
第二步进行Class的
<clinit>()
初始化。
3.1. Classloader加载过程
find/load: 将文件反序列化为C结构体。
link: 根据Class结构体常量池进行符号的解引。比如对象计算内存空间,创建方法表,native invoker,接口方法表,finalizer函数等工作。
3.2. 初始化过程
public
class
Sample {
//step.1
static
int
b =
2
;
//step.2
static
{
b =
3
;
}
public
static
void
main(String[] args) {
Sample s =
new
Sample();
System.out.println(s.b);
//b=3
}
}
When and how a Java class is loaded and initialized?
The Lifetime of a Type
4. 反射在native的实现
4.1. Class.forName的实现
4.2. getDeclaredFields的实现
根据Class结构体信息,获取
field_count
与fields[]
字段,这个字段早已在load过程中被放入了根据
field_count
的大小分配内存、创建数组将数组进行forEach循环,通过
fields[]
中的信息依次创建Object对象返回数组指针
创建、计算、分配数组对象
对字段进行循环赋值
4.3. Method.invoke的实现
创建Frame
如果对象flag为native,交给native_handler进行处理
在frame中执行java代码
弹出Frame
返回执行结果的指针
需要完全执行ByteCode而缺少JIT等优化
检查参数非常多,这些本来可以在编译器或者加载时完成
4.4. class.newInstance的实现
检测权限、预分配空间大小等参数
创建Object对象,并分配空间
通过Method.invoke调用构造函数(
<init>()
)返回Object指针
参数检查不能优化或者遗漏
<init>()
的查表Method.invoke本身耗时
5. 附录
5.1. JVM与源码阅读工具的选择
5.2. 关于几个ClassLoader
//sun.misc.Launcher$AppClassLoader@4b67cf4d//which class you create or jars from thirdParty//第一个非常有歧义,但是它的确是AppClassLoaderClassLoader.getSystemClassLoader();
com.test.App.getClass().getClassLoader();Class.forName(
"ccom.test.App"
).getClassLoader()
//sun.misc.Launcher$ExtClassLoader@66d3c617//Class loaded in ext jarClass.forName("sun.net.spi.nameservice.dns.DNSNameService")//null, class loaded in rt.jarString.class.getClassLoader()Class.forName("java.lang.String").getClassLoader()Class.forName("java.lang.Class").getClassLoader()Class.forName("apple.launcher.JavaAppLauncher").getClassLoader()
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
try
{
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
// call some API that uses reflection without taking ClassLoader param} finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
5.3. 反射是否慢?
验证等防御代码过于繁琐,这一步本来在link阶段,现在却在计算时进行验证
产生很多临时对象,造成GC与计算时间消耗
由于缺少上下文,丢失了很多运行时的优化,比如JIT(它可以看作JVM的重要评测标准之一)
参考文献
http://www.codeceo.com/article/reflect-bad.html
http://blog.csdn.net/lmj623565791/article/details/43452969
http://codekk.com/open-source-project-analysis/detail/Android/Trinea/%E5%85%AC%E5%85%B1%E6%8A%80%E6%9C%AF%E7%82%B9%E4%B9%8BJava%20%E6%B3%A8%E8%A7%A3%20Annotation
http://www.trinea.cn/android/java-annotation-android-open-source-analysis/
- Java反射在JVM的实现
- Java反射在JVM的实现
- Java反射在JVM的实现
- Java反射在JVM的实现
- Java反射在JVM的实现
- Java反射在JVM中的实现
- Java反射的实现
- JAVA反射的实现方式
- 反射的概念及在Java中的类反射
- Java用反射机制在不看类的实现方法下查看类的相关信息
- synchronized在JVM底层的实现原理及Java多线程锁理解
- java反射机制的实现原理 (二)安全性和反射
- jvm的实现版本(java虚拟机)
- 在C++实现反射
- 在C++实现反射
- 在C++实现反射
- 在C++实现反射
- java反射机制的简单实现步骤
- 给新手的最佳类Windows界面的Linux发行版
- 十九、UI-Grid 水平滚动
- RN基础以及组件学习技巧
- 1002. 写出这个数 (20)
- Typescript结合gulp开发
- Java反射在JVM的实现
- JS判断浏览器是否安装flash插件的简单方法
- Intersection of Two Linked Lists
- KNN(二)--近似最近邻算法ANN
- 时间日期格式转换 oj
- 12个助你提升ios app开发效率的工具
- canvas 绘制大乐透数据图表
- android lcd调试 高通平台lcd调试深入分析总结(mipi和rgb接口)
- ionicPopup 屏蔽物理返回键的解决方案