JVM加载类过程的总结

JVM类的加载
JVM是Java虚拟机,每当一个Java程序运行时都会有一个JVM实例,只有当程序结束运行后这个JVM才退出。Jvm实例通过调用MAIN函数来启动一个JAVA 程序,也就是找到main函数然后进行相关类的加载。
类的加载主要有三个步骤:
1.装载。根据查找路径找到相应的class文件,然后导入。
2.链接。具体再分为三个步骤
     (1)检查 检查class文件的正确性
     (2)准备 给类中的静态变量分配空间
     (3)解析 将符号引用转换为直接引用(可选)
3.初始化。对静态变量和静态代码块块执行初始化工作

具体的举个例子来说明一下(代码来自互联网)
class Insect
{
      private int i =9;
      protected int j ;
     Insect()
     {
           System. out .println( "i=" + i + " j=" + j );
            j = 39;
     }
      private static int x = printInit( "static Insect.x initialized" );
      static int printInit(String s )
     {
           System. out .println( s );
            return 47;
     }
     
}
public class Beetle extends Insect
{
      private int k = printInit( "Bettle.k initialized" );
      public Beetle()
     {
           System. out .println( "k=" + k + " j=" + j );
     }
      private static int x2 = printInit( "static beetle initialized" );
      public static void main(String[] args )
     {
           System. out .println( "bettle constructor" );
           Beetle b = new Beetle();
     }
}
运行结果:
对于这个java文件,在运行时程序一开始试图找到Beetle的main方法然后加载Beetle的class文件,在class文件加载的过程中,发现这个Beetle类继承了另外一个类Insect所以程序需要先加载Insect的class文件。在加载过程中会执行类加载的三个步骤,遇到静态变量惊醒初始化,之后再加载自身的class文件,同样遇到static修饰的也会初始化。所以会先输出
static Insect.x initialized
static beetle initialized
此时如果Insect类继承了另外一个类时,以同样的方法类推。

总结类初始化的顺序:
父类静态变量,父类静态代码块,子类静态变量,子类静态代码块,父类非静态变量,父类非静态代码块,父类构造函数,子类非静态变量,子类非静态代码块,子类构造函数。

ps: 如果去掉main函数,则会出现如下结果:
JVM类的加载
JVM是Java虚拟机,每当一个Java程序运行时都会有一个JVM实例,只有当程序结束运行后这个JVM才退出。Jvm实例通过调用MAIN函数来启动一个JAVA 程序,也就是找到main函数然后进行相关类的加载。
类的加载主要有三个步骤:
1.装载。根据查找路径找到相应的class文件,然后导入。
2.链接。具体再分为三个步骤
     (1)检查 检查class文件的正确性
     (2)准备 给类中的静态变量分配空间
     (3)解析 将符号引用转换为直接引用(可选)
3.初始化。对静态变量和静态代码块块执行初始化工作

具体的举个例子来说明一下(代码来自互联网)
class Insect
{
      private int i =9;
      protected int j ;
     Insect()
     {
           System. out .println( "i=" + i + " j=" + j );
            j = 39;
     }
      private static int x = printInit( "static Insect.x initialized" );
      static int printInit(String s )
     {
           System. out .println( s );
            return 47;
     }
     
}
public class Beetle extends Insect
{
      private int k = printInit( "Bettle.k initialized" );
      public Beetle()
     {
           System. out .println( "k=" + k + " j=" + j );
     }
      private static int x2 = printInit( "static beetle initialized" );
      public static void main(String[] args )
     {
           System. out .println( "bettle constructor" );
           Beetle b = new Beetle();
     }
}
运行结果:
对于这个java文件,在运行时程序一开始试图找到Beetle的main方法然后加载Beetle的class文件,在class文件加载的过程中,发现这个Beetle类继承了另外一个类Insect所以程序需要先加载Insect的class文件。在加载过程中会执行类加载的三个步骤,遇到静态变量惊醒初始化,之后再加载自身的class文件,同样遇到static修饰的也会初始化。所以会先输出
static Insect.x initialized
static beetle initialized
此时如果Insect类继承了另外一个类时,以同样的方法类推。

总结类初始化的顺序:
父类静态变量,父类静态代码块,子类静态变量,子类静态代码块,父类非静态变量,父类非静态代码块,父类构造函数,子类非静态变量,子类非静态代码块,子类构造函数。

ps: 如果去掉main函数,则会出现如下结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值