反射、类加载和new一个对象的过程的底层

  这段时间比较好奇类加载的一个过程,正好在知乎上看到了其中一个比较有意思的地方,就是创建一个对象的过程,描述的更加底层,这里做一个分享。
知乎链接:
https://www.zhihu.com/question/24304289

1.创建对象的过程,或者说new一个对象的过程如下:

在这里插入图片描述
  简单地描述就是,先把我们的.class文件进行类加载,然后把类文件信息存储在方法区中,并在堆内存中为我们的对象开辟一个空间。

2.对于反射的理解

  假如你写了一段代码:Object o=new Object();运行了起来!

  首先JVM会启动,你的代码会编译成一个.class文件,然后被类加载器加载进jvm的内存中,你的类Object加载到方法区中,创建了Object类的class对象到堆中,注意这个不是new出来的对象,而是类的类型对象,每个类只有一个class对象,作为方法区类的数据结构的接口。jvm创建对象前,会先检查类是否加载,寻找类对应的class对象,若加载好,则为你的对象分配内存,初始化也就是代码:new Object()。

  上面的流程就是你自己写好的代码扔给jvm去跑,跑完就over了,jvm关闭,你的程序也停止了。

  为什么要讲这个呢?因为要理解反射必须知道它在什么场景下使用。

  可以想想上面的程序对象是自己new的,程序相当于写死了给jvm去跑。假如一个服务器上突然遇到某个请求哦要用到某个类,哎呀但没加载进jvm,是不是要停下来自己写段代码,new一下,哦启动一下服务器,(脑残)!

  反射是什么呢?当我们的程序在运行时,需要动态的加载一些类这些类可能之前用不到所以不用加载到jvm,而是在运行时根据需要才加载,这样的好处对于服务器来说不言而喻,举个例子我们的项目底层有时是用mysql,有时用oracle,需要动态地根据实际情况加载驱动类,这个时候反射就有用了,假设 com.java.dbtest.myqlConnection,com.java.dbtest.oracleConnection这两个类我们要用,这时候我们的程序就写得比较动态化,通过Class tc = Class.forName(“com.java.dbtest.TestConnection”);通过类的全类名让jvm在服务器中找到并加载这个类,而如果是oracle则传入的参数就变成另一个了。这时候就可以看到反射的好处了,这个动态性就体现出java的特性了!举多个例子,大家如果接触过spring,会发现当你配置各种各样的bean时,是以配置文件的形式配置的,你需要用到哪些bean就配哪些,spring容器就会根据你的需求去动态加载,你的程序就能健壮地运行。

作者:chsfjz
链接:https://www.zhihu.com/question/24304289/answer/147529485
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3.对于类加载的理解

  类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的java.lang.Class对象,用来封装类在方法区类的对象。

类加载又分为几个步骤:
1)装载:查找并加载类的二进制数据;
2)链接:(细分为三个步骤)
验证:确保被加载类的正确性;
准备:为类的静态变量分配内存,并将其初始化为默认值;
解析:把类中的符号引用转换为直接引用;
3)初始化:为类的静态变量赋予正确的初始值;

那么上面说的符号引用和直接引用时什么呢?
符号引用时以一组符号来描述所引用的目标,引用目标并不一定加载到内存中;
直接引用可以指向目标的指针、相对偏移量或者是一个能够直接定位到目标的句柄,所引用的目标一定已经在内存中存在。

最近一看,被自动设置为VIP文章了,感觉不方便大家学习,于因此取消掉了VIP观看。
觉得不错可以点赞或关注哟~

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Android中,一个对象过程可以分为以下几个阶段: 1. 类:当应用程序启动时,Dalvik或ART虚拟机会通过类应用程序的类。类是一个动态的过程,根据需要逐个类。在类过程中,虚拟机会检查类的字节码是否合法,并对类进行初始化。 2. 对象实例化:当类被后,可以通过关键字`new`或反射等方式创建该类的实例。对象实例化的过程中,虚拟机会为对象分配内存空间,并初始化对象的成员变量。 3. 构造方法调用:在对象实例化完成后,虚拟机会调用对象的构造方法来完成对象的初始化操作。构造方法是一个特殊的方法,用于初始化对象的状态。 4. 对象初始化:在构造方法被调用后,虚拟机会执行对象的初始化代码块和实例变量的赋值操作。初始化代码块是一个用`{}`包围的代码块,它在每次创建对象时都会执行。 5. 对象就绪:当对象完成初始化后,就进入了就绪状态。此时,对象可以被使用,并响应相应的方法调用。 需要注意的是,对象过程并不是一次性完成的,而是在需要使用该对象时才触发相应的和初始化操作。例如,在Android中,一个Activity的对象通常在其对应的生命周期方法(如`onCreate()`)中被创建和初始化。 此外,在Android中还有一些特殊情况需要考虑,例如对象的状态保存和恢复、对象的序列化与反序列化等。在这些情况下,对象过程可能会有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值