Java中new和反射创建对象的区别(底层)

2020.11.17
查阅了很多资料,依然有些懵懂的地方,有错之处,还请大家多多指教。

Java中new创建对象

图来自知乎图来自知乎

如果我们在代码中如果写了一段

A a = new A();

在JVM中会帮你做的事情有以下:

  1. JVM把类的.java文件编译为一个.class的字节码文件
  2. 类加载器把.class文件加载进jvm的内存中,一个Class对象生成,并放入方法区中,这Class对象对于任何类都是唯一一个。

做完这些之后,才是new字段的工作:

  1. 判断内存中是否已经有那个唯一的Class对象
  2. 如果没有,则进行上述操作。
  3. 如果有,则在内存中申请空间开辟,即根据Class对象获取有关的构造器进行实例化,在这里我们假设是一个无参数构造,那么只需要newInstance()。

Java中使用反射创建对象

依然是上面这一幅图,但是我们这次的代码是我们最常见的反射代码

Class c = Class.forName("A的全类名");

当JVM编译到这段代码的时候,他的步骤是:
1、使用类加载,将对应.class加载入内存的方法区中,并返回Class对象。
这时候,我们可以查看这个类对象里面的构造器方法,并使用无参数构造器进行构造实例,即如下代码

Constructor constructor = c.getConstructor();
Object obj = constructor.newInstance();

用同样的图,我们可以画出来。
在这里插入图片描述到这里,我们几乎可以知道无论是反射,还是New,其实都是通过类加载器对.class文件加载进内存中,创建了Class对象。‘’

那么,在其他博客中提到的动态编译和静态编译就好理解了。
Java中反射属于动态编译,而new属于静态编译。

粗俗解释:

1、静态编译相当于把所有需要的东西都在初始化的时候加载了,如果程序一大,就很有可能会跑得慢。

2、动态编译,在编译的时候,需要的模块都没有编译进去,启动程序的时候,模块不会被加载而是在运行的时候,需要哪个模块就调用哪个模块。

上面的过程告诉我们,我们如果用new,那么我们要创建的类都是已经“写死”在.class文件里面了,我们无法控制JVM帮我们加载类的这一项工作。

但是如果我们用反射创建类对象,我们是相当于亲自“指导”JVM,我们“按需加载”.class文件,如果内存里面没有这个类的.class文件,那么我们用Class.forName()去叫类加载器帮忙加载就行了,而不是把程序停下来,再打一段代码,再让类加载器进行加载,从而体现出了Java的“动态性”。

参考资料有:
知乎

  • 30
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值