classLoader和内存分析

 

类的初始化和对象实例化
反射机制的目的就是通过类加载获取到字节码文件(运行中的类)的内部数据结构,再对这些获取的信息进行操作,如获取类对象、创建对象实例、获取方法名、调用方法、获取方法参数类型和方法返回类型等。
 
理解反射前要先了解类的加载及JVM内部的存储机制
 
类加载时通过   1.  加载
                   ->2.链接      验证(完全性校验)、准备(为静态数据赋予初始值基本数字数据类型为0,boolea型为false,string为null,对象为null)、解析(将符号引用转化为地址引用,为了能够直接在内存中找到数据)
                   ->3.类初始化   执行静态变量、方法并进行赋值
 
第一个加载过程中:将java文件转换为字节码class文件,在这个转变过程中 将java文件中的信息存到三个区域(堆、栈、方法区)
     方法区(特殊的堆): 存放了类结构模板信息    1.代码块 (类的属性、方法、代码)    2.静态变量      3.常量池   
     堆:        存放了java.lang.class对象,该对象的作用是访问 方法区的数据结构从而操作类的信息 (反射就是完成这个过程),类的成员变量在对象实例化后通过方法区的数据结构信息存在该区,static成员变量则在类加载初始化后就存在该区了
     栈:        存放  方法地址、局部变量等,
程序运行内存分析:
          比如存在局部变量A a = new A; 过程中在 中创建a,通过new创建对象(调用构造器), 堆参照方法区中加载类的数据结构创建了A的对象,并且将A对象的地址赋值给了栈中的a(引用),而堆中的这个对象通过引用访问方法区中的数据信息,如给对象赋值某个字符串常量,就是通过A对象中的引用地址访问方法区中的常量池(对象中基本数据类型可直接赋值,无需引用)。如图高琪类加载机制
 
反射的作用
     1).获取字节码文件信息,类名和方法名
     2).获取该类名对应的字节码文件对象
     3).获取指定的方法对象
     4).创建该字节码文件对象
     5).调用方法运行
 
JDK中有多个classLoader,如下:
类加载机制
类加载器classloader:负责将类文件加载到内存
类主要是通过ClassLoader及其子类完成加载的,类的层次关系加载顺序如下
1.检查(自下而上):该过程中只要检查到某个classloader已经存在则认为该类已经加载了,保证此类所有classloader只加载一次
 
    bootstraploader (启动类加载器): 负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,加载jdk core中的核心类由C++实现
             |  
    extension classloader( 标准扩展类加载器): 负责加载java平台中扩展功能的一些jar包,一般在JDK的目录“Java\jre7\lib\ext”目录下
                                                                        该文件中得了类属于JDK自带引用类,可直接使用,eclipse目录中为JRE Syetem library
             |
    app classloader( 系统类加载器):负责加载classpath中指定的包,一般加载为用户自己定义的class,
             |
    other classloader:加载其他类型的class   SecureClassLoader URLClassLoader等 
 
各个classloader之间是用过getParent()方法在内存拿到引用对象的相互关联(非继承关系)。
在加载一个类时会先通过getParent()引用查找上级加载器是否加载过们,如果加载过则当前加载器不再加载
 
String str = "T"
Class c = class.forName(str);                       获取类名为T的类对象               
Object o = c.newInstace();                          为对象创建实例                       //该两句实现了关键字new的加载类、生成实例的作用     
Method[] methods = c.getMethods();               获取类的方法成员
for(Method m:methods){
     if(m.getName().equals("方法名"))                核对 m对象中的方法是否存在
         m.invoke(o);                                          调用该方法
}
二、细节补充
(1)对比:forName和getClassLoader(); http://carl-java.iteye.com/blog/978680
class. forName除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。而classLoader只干一件事情,就是将.class文件加载到jvm中(即只链接,不做初始化),不会执行static中的内容,只有在newInstance才会去执行static块。
 
(2)对比:new 和 newInstance
newInstance: 弱类型。低效率。只能调用无参构造。
new: 强类型。相对高效。能调用任何public构造。
newInstance()是实现IOC、反射、面对接口编程 和 依赖倒置 等技术方法的必然选择,new 只能实现具体类的实例化,不适合于接口
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值