new都干了些什么

用Java写代码的时候,感觉用的最多的便是new了吧,这几天在恶补Java基础知识的时候突然想到,我们在new一个对象时JVM具体都做了什么操作,且它们的顺序是什么样子的呢?于是我就写了一个小Demo,通过查看运行结果和Debug来看一下

首先定义一个Person类:
public class Person {
    
    private int age = 1;
    static String country = "CN";

    //静态代码块
    static {
        System.out.println("static code block 1");
    }

    //构造代码块
    {
        System.out.println("constructed code block");
    }

    Person() {
        System.out.println("I'm a person");
    }

    //这个静态代码块放在最后,用来测试执行顺序
    static {
        System.out.println("static code block 2");
    }
}
然后写一个类用来验证结果:
public class UsingStaticCodeBlock {
    public static void main(String[] args) {
        System.out.println("begin");
        Person p1 = new Person();
    }
}
  1. Person p1 = new Person();这一行前加一个断点,开始进行Debug。首先在控制台打印出"begin"这就不多说了
    按F5进入之后,发现断点到了这个地方
    众所周知,当要用到一个类时,JVM会把类加载到内存中去,而且可以发现,接下来要执行的语句是static String country = "CN";而不是int age = 1;故可以证明,类加载时会把其中的静态成员变量放到方法区(也叫全局区或者静态区)中,并进行默认初始化和赋值(此处为null->"CN")

继续F5进行调试,程序来到了第一个静态代码块,按F6执行后,直接跳到第二个静态代码块,再按F6,输出结果



第一个静态代码块执行后的控制台

第二个静态代码块执行后的控制台

可以看出,静态代码块在静态变量初始化和赋值后执行,执行顺序由上而下

  1. 按F6跳回UsingStaticCodeBlock.java,再按F5跳转到构造方法Person()
    再按F5,程序没有进入构造函数,而是跳转到了private int age = 1;这一行
    这说明JVM开始为对象在堆内存中分配空间并对其实例变量进行初始化和赋值(此处0->1),按F5执行完后程序跳转到构造代码块
    说明构造方法执行前还要执行构造代码块,按F6执行结果如下图
    现在程序跳转到了构造方法中
    按F6执行后,结果如下
    一直按F6直到Person p1 = new Person()执行完毕,此时new新建对象就全部完成了,对象的首地址赋给了存在栈内存中的变量p1,使p1指向了这个对象

简单的一条new语句,执行起来却复杂的很。但是为什么在调试过程中会跳回UsingStaticCodeBlock.java一次呢?经过查看Debug窗口的方法调用信息发现,第1步与第2步实际调用的方法是不一样的


第1步

第2步

通过查阅资料知道,首先进行的是类初始化,然后再进行实例初始化

结论

  1. 首先加载类到内存中
  2. 如果有,初始化静态变量并赋值,然后执行静态代码块
  3. 在堆内存中开辟空间,分配内存,初始化实例变量并赋值(如果有),然后执行构造代码块和构造函数
  4. 对象首地址赋给栈内存中的引用变量
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,703评论 0 11
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,785评论 18 399
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 7,145评论 0 62
  • 前言 看大神推荐的书单中入门有这么一本书,所以决定把这本书的精华(自认为很有用的点),或许是我自己现在能用到的点都...
    我没有三颗心脏阅读 2,298评论 0 6
  • 所有想起都是不曾忘记~ 我和我的过去 总是相互留恋相互依靠 你都不知道 突然的想起 有多么的温暖
    布娃娃与不娃娃阅读 264评论 0 0