类加载和类实例化

Java程序中对类的使用方式分为两类 :主动使用和被动使用

主动使用:

  1. 创建类的实例
  2. 访问某个类或接口的静态变量,或者对该静态变量赋值
  3. 调用类的静态方法
  4. 反射
  5. 初始化一个类的子类
  6. java虚拟机启动时被标明为启动类的类
  7. 从JDK1.7开始提供的动态语言支持:java.lang.invoke.MethodHandle实例的计息结果REF_getStatic,REF_putStatic,REF_involeStatic句柄对应的类没有初始化,则初始化
    被动使用:
    除了以上7中情况,其他适用java类的方法都被看做是对类的被动使用,都不会导致类的初始化。
    创建类的实例——创建对象
    *注:A是一个拥有属性的类。
    (1)声明对象时的内存模型
    用A a;声明一个对象a时,将在栈内存为对象的引用变量a分配内存空间,但A的值为空,称a是一个空对象。空对象不能使用,因为它还没有引用任何”实体”。
    (2)对象实例化时的内存模型
    当执行a=new A(3,5);时,会有连接和初始化两个过程。
    连接:连接又分为验证、准备、解析三个小步骤。在准备过程中,JVM会在堆内存中为类的成员变量分配内存,并将其初始化为各数据类型的默认值;接着进行显式初始化(类定义时的初始化值),此时,在到达初始化之前,类变量都没有初始化为真正的初始值;
    解析:解析过程就是在类型的常量池中寻找类、接口、字段和方法的符号引用,把这些符号引用替换成直接引用的过程。
    初始化:最后调用构造方法,为成员变量赋值。返回堆内存中对象的引用(相当于首地址)给引用变量a,以后就可以通过a来引用堆内存中的对象了,此过程为类变量的真正赋初始值。
    (3)创建多个不同的对象实例
    一个类通过使用new运算符可以创建多个不同的对象实例,这些对象实例将在堆中被分配不同的内存空间,改变其中一个对象的状态不会影响其他对象的状态。例如:
A  a1= new A(3,5);
A  a2= new A(4,6);

此时,将在堆内存中分别为两个对象的成员变量分配内存空间,两个对象在堆内存中占据的空间是互不相同的。如果有:

A  a1=new A(3,5);
A  a2=a1;

则在堆内存中只创建了一个对象实例,在栈内存中创建了两个对象引用,两个对象引用同时指向一个对象实例。

猜你喜欢

转载自blog.csdn.net/weixin_45457983/article/details/107130062