zoukankan      html  css  js  c++  java
  • jvm类加载_类的流程

    类的流程

          

          

          类的加载流程各阶段说明:

             全限定名 : 包名 + 类名

             加载 :  1. 根据类的全限定名找到对应的二进制流

                        2. 将静态数据结构转换为方法区运行时数据结构

                        3. 在堆中生成一个java.lang.class对象,作为访问方法区这些数据的入口

              验证 : 校验字节码正确性 和 二进制流正确性等,其目的就是为了保证jvm的正确运行.

              准备 : 为类中的静态变量准备分配内存,并赋予其默认值

                       如 int a = 5 .  Integer b = 10 . 在这里 a =0 , b =null  . 在真正初始化的时候才会为其赋予真正的值

                       常量的初值即为代码中设置的值,final static tmp = 456, 那么该阶段tmp的初值就是456

              解析 : 将类中的符号引用转换为直接引用

                         符号引用 : 一个字符串,但是这个字符串给出了可以唯一识别一个类,方法,变量的相关信息

                         直接引用 : 可以理解为内存地址或者偏移量 . 当为一个类变量或者类方法时, 直接引用代表指向方法区的一个指针 . 当为实例时,直接引用代表 从这个实例的头指针算起,到这个实例位置的偏移量.

                         在此阶段,虚拟机会把次类中的方法名,变量名,类名这些符号引用转换为直接引用.

              初始化 :  执行构造器 <client>方法 . 换句话说, 这个时候只对 类变量或者静态代码块进行初始化

                         如 上面的 a此时值为5 , b = 10

                         如果存在多个静态变量或者静态代码块,从上至下顺序执行.

                         此阶段,如果发现此类存在父类,且父类未进行初始化,则优先初始化父类

    Java虚拟机规范中严格规定了以下情况必须对类进行初始化:

           

           1. 直接new此对象的实例

           2. 对一个类的静态变量进行读取或者重新赋值

           3. 虚拟机启动时,  把此类作为执行的主类

           4. 通过java.lang.reflect 对此类进行反射 (其实反射好像也是通过调用构造方法来初始化得到的对象)

           5. 初始化一个类的子类

    示例 :

    //父类  
    public class SuperClass {  
        //静态变量value  
        public static int value = 666;  
        //静态块,父类初始化时会调用  
        static{  
            System.out.println("父类初始化!");  
        }  
    }  
     
    //子类  
    public class SubClass extends SuperClass{  
        //静态块,子类初始化时会调用  
        static{  
            System.out.println("子类初始化!");  
        }  
    }  
     
    //主类、测试类  
    public class NotInit {  
        public static void main(String[] args){  
            System.out.println(SubClass.value);  
        }  
    }

    输出 :  父类初始化!  666

            1. 静态常量在编译阶段就会被存入调用类的常量池中,不会引用到定义常量的类,这是一个特例,需要特别记忆,不会触发类的初始化!



        //父类  
     
       public class SuperClass {  
            //静态变量value  
            public static int value = 666;  
            //静态块,父类初始化时会调用  
            static{  
                System.out.println("父类初始化!");  
            }  
        }  
          
        //主类、测试类  
        public class NotInit {  
            public static void main(String[] args){  
                SuperClass[] test = new SuperClass[10];  
            }  
        }  

    输出 :  什么也没有

            2. 通过数组来引用类,不会触发类的初始化,因为是数组new,而类没有被new

     

                         

     

         

             

    人总得做点什么 ,不是么
  • 相关阅读:
    [Cogs727] [网络流24题#2] 太空飞行计划 [网络流,最小割]
    [Cogs14] [网络流24题#1] 飞行员分配方案 [网络流,最大流,二分图匹配]
    [Poj2112][USACO2003 US OPEN] Optimal Milking [网络流,最大流][Dinic+当前弧优化]
    基本高精度模板
    Dinic模板
    [poj1698]Alice's Chance[网络流]
    [cf 599D] Spongebob and Squares
    [cf 599C] Day at the Beach
    [BZOJ1004]Cards
    [BZOJ1007]水平可见直线
  • 原文地址:https://www.cnblogs.com/liweibing/p/12661773.html
Copyright © 2011-2022 走看看