搜索

首页  >  问答  >  正文

java类加载机制-类定义中new如何理解

高洛峰高洛峰2801 天前881

全部回复(5)我来回复

  • 黄舟

    黄舟2017-04-18 10:48:41

    在运行 java 程序的时候,每个类只被加载一次。不可能重复加载的。所以也就不存在题主说的递归了。

    回复
    0
  • PHP中文网

    PHP中文网2017-04-18 10:48:41

    推荐先了解一下JVM虚拟机中内存

    AVA对象实例化过程中,主要使用到的包括虚拟机栈,JAVA堆和方法区。
    JAVA文件经编译之后首先会被加到到JVM方法区,JVM方法区中很重要的一个部分是运行时常量池——用以存储class文件类的版本、字段、方法、接口等描述信息和编译期间的常量和静态变量。
    JAVA对象真正进行实例化的地方在JAVA堆和虚拟机栈中,Object A = New Object();在实际内存中,A其实相当于我们给Ojbect这个类的实现起的一个名字,在面向对象编程中,就像狗是属于一类动物,但是特指的那一条狗我们会给他起一个名字用以区分一样。Object用以标记A是属于这个类,而A是特指Object的一个具体实现,而New Object就相当于对这个类创建一个具体实现。所以我们可以了解到,一个对象他首先必须可以指明所属的类,其次它还必须能指明他所特指的哪一个具体实现。
    对应的有两种实现方式:

    1.句柄访问对象

    2.直接指针访问对象
    直接指针访问对象

    HotSpot采用的是第二种实现方式。
    Class的装载包括3个步骤:加载(loading),连接(link),初始化(initialize)
    加载
    根据上图所示,我们不难理解,当一个对象进行实例化的时候,JVM会根据所需对象类型在JAVA堆中划分内存区,并生成指向方法区对象数据类型的指针用以标识对象。
    链接
    虚拟机栈中的本地变量表(也有称为局部变量表)中指针指向JAVA堆中划分好的内存区域。JAVA虚拟机采用动态链接方式,只有编译后的class文件并未存储最终方法在内存的表现形式。
    初始化
    初始化实际上是对class文件中的初始化方法进行调用,其核心还是虚拟机栈中栈帧的一次POP/PUSH。相当于对类中的对象进行一次同样的装载过程。
    至此,一个对象完整的实例化过程就全部介绍完毕。

    类内部初始化顺序为 静态域->非静态域->构造方法

    推荐看一下:
    【JAVA笔记——道】对象生命周期详解
    【JAVA笔记——道】Class初始化理解

    回复
    0
  • PHPz

    PHPz2017-04-18 10:48:41

    是不是把类加载和对象初始化搞混了?

    回复
    0
  • 怪我咯

    怪我咯2017-04-18 10:48:41

    楼主是不是想的太高深了?实例化和声明定义是2个概念和阶段。
    A2有几个静态的成员变量在声明时实例化,而类的实例化过程是通过构造函数完成的。
    这里看上去出现了嵌套,其实不然。编译器可以在编译实例化语句的时候申明指令跳转,跳转地址在二次编译的时候确定。
    这样,类申明阶段,在实例化a,b,c,d的时候编译程序会跳转到A2(int i)的构造方法程序块。
    在类实例化阶段的时候跳转到A()构造方法。
    说白了就是在不同阶段调用对应的构造方法而已,没有楼主以为的循环嵌套。

    回复
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:48:41

    类加载时,对于静态变量和构造方法的加载顺序不一样吧。构造方法本质也是静态方法。
    也不怎么懂,先占个板凳

    回复
    0
  • 取消回复