【问题驱动学习】-当你new一个对象的时候,JVM都做了什么?

3 篇文章 0 订阅

构造器

Java代码里面用new生成一个对象的时候,JVM会执行用来请求内存的 new 指令,以及用来调用构造器的 invokespecial 指令。通过使用javap命令查看生成的字节码,就能清晰的看到。

// Foo foo = new Foo(); java代码
  0 new Foo  //申请内存
  3 dup
  4 invokespecial Foo() //调用构造器
  7 astore_1

如果一个类没有定义任何构造器的话,就不会有第二个操作了吗?答案是否定的,及时类中没有任何构造器,Java编译器会自动添加一个无参构造器,如果没有继承其他类,父类就是Object,所以会自动调用Object的无参构造函数。

// Foo类构造器会调用其父类Object的构造器
public Foo();
  0 aload_0 [this]
  1 invokespecial java.lang.Object() [8]
  4 return
代码验证

写两个简单的类来验证。

public class ParentClazz {
    private String name;
}
public class ChildClazz extends ParentClazz {
    private String childName;
}

编译代码,并查看字节码

#javac ParentClazz.java ChildClazz.java
#javap -v ParentClazz.class
public micreeson.learning.jvm.clazz.ParentClazz();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0
#javap -v ChildClazz.class
public micreeson.learning.jvm.clazz.ChildClazz();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method micreeson/learning/jvm/clazz/ParentClazz."<init>":()V
         4: return
      LineNumberTable:
        line 4: 0

成员变量

通过 new 指令新建出来的对象,它的内存其实涵盖了所有父类中的实例字段。也就是说,虽然子类无法访问父类的私有实例字段,或者子类的实例字段隐藏了父类的同名实例字段,但是子类的实例还是会为这些父类实例字段分配内存的
这点可以使用jvisualvm来查看子类对象的成员来验证

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值