zoukankan      html  css  js  c++  java
  • 实列+JVM讲解类的实列化顺序

    刨根问底---类的实列化顺序

    开篇三问

    • 1什么是类的加载,类的加载和类的实列有什么关系,什么时候类加载

    • 2类加载会调用构造函数吗,什么时候调用构造函数

    • 3什么是实列化对象,实列化的对象有什么东西。
      我们先做一个实验,截图来自:https://blog.csdn.net/u011517841/article/details/82657047
      public class Text {
      public static int k = 10;
      public int a = print("a");
      public static int b = print("b");
      public static Text t1 = new Text("t1");
      public static Text t2 = new Text("t2");
      public static int i = print("i");
      public static int n = 99;
      public int j = print("j");
      public int m = print("m");

          {
              print("构造块");
          }
          static {
              print("静态块");
          }
          
          public int l = print("l");
          public static int o = print("o");
          
          public Text(String str) {
              System.out.println("构造:" + (++k) + ":" + str + "   i=" + i + "    n=" + n);
              ++i;
              ++n;
          }
       
          public static int print(String str) {
              System.out.println("print:" + (++k) + ":" + str + "   i=" + i + "    n=" + n);
              ++n;
              return ++i;
          }
          
          public int p = print("p");
       
          public static void main(String args[]) {
              Text t = new Text("init");
          }
      }
      

      结果:
      print:11:b i=0 n=0
      print:12:a i=1 n=1
      print:13:j i=2 n=2
      print:14:m i=3 n=3
      print:15:构造块 i=4 n=4
      print:16:l i=5 n=5
      print:17:p i=6 n=6
      构造:18:t1 i=7 n=7
      print:19:a i=8 n=8
      print:20:j i=9 n=9
      print:21:m i=10 n=10
      print:22:构造块 i=11 n=11
      print:23:l i=12 n=12
      print:24:p i=13 n=13
      构造:25:t2 i=14 n=14
      print:26:i i=15 n=15
      print:27:静态块 i=16 n=99
      print:28:o i=17 n=100
      print:29:a i=18 n=101
      print:30:j i=19 n=102
      print:31:m i=20 n=103
      print:32:构造块 i=21 n=104
      print:33:l i=22 n=105
      print:34:p i=23 n=106
      构造:35:init i=24 n=107

      分析:
      1.首先程序启动时会去找main函数吧,要想使用main函数首先会对有此main函数的类进行加载,验证,准备,初始 化。准备的时候会为类变量分配内存,初始化为默认值。因此准备的时候只会去加载静态变量。此阶段没有打印值

      2.初始化阶段:初始化阶段会为静态变量赋值和运行静态代码块。此阶段会print(b),然后new Text("text1).
        在碰到new 的时候回去初始化一个Text对象。因此会打印a,j,m,会执行代码块打印构块,然后打印l,p最后再调用构造函数。紧接着new Test("text2)就同理了。然后紧接着又继续类的初始化阶段打印i,静态块,o
        
      3.生成对象:就是初始化类的实列成员,然后调用构造函数的过程。
      

      增加有父类的情况
      public class JVMParent {

      	 public static int width = 100;
      	 
      	 public static int count;
      	 
      	 {
      		 System.out.println("parent no static code block :" + count);
      	 }
      	 
      	 static{
      		 System.out.println("parent static's count:" + count);
      	 }
      	 
      	 JVMParent(int a){
      		 System.out.println("parent init one parameter");
      	 }
      	 
      	 JVMParent(){
      		 System.out.println("parent init");
      	 }
      	 
      }
      public class JVMSon extends JVMParent {
      	
      	 
      	 {
      		 System.out.println("son no static code block :" + count);
      	 }
       
      	static {
      		System.out.println("son static 1");
      	}
       
      	public static int count1;
       
       
      	JVMSon() {
      		System.out.println("son init:" + count);
      	}
       
      	static {
      		System.out.println("son static 2");
      	}
       
      	public static void main(String[] args) {
      		System.out.println("son main start");
      		JVMSon a = new JVMSon();
       
      	}
       
      }
      

      答案
      parent static's count:0
      son static 1
      son static 2
      son main start
      parent no static code block :0
      parent init
      son no static code block :0
      分析
      1.首先要加载Son类,因为它有main函数,但是它有父类,必须先加载父类。因此先加载父类,准备,初始化,然后解析。准备阶段打印:parent static's count。然后加载子类,打印son static 1,son static 2.现在类的准备阶段完毕。
      2.执行main函数:打印son main start
      3.实列化对象:先初始化父类,parent no static code block :0,调用父类的构造函数,然后初始化子类。
      感觉这部分逻辑有问题。。。。。。

  • 相关阅读:
    如何解决虚拟机频繁分离和附加磁盘导致的识别错误
    创建基于 AFS 的 Docker 容器卷
    使用 docker-machine 管理 Azure 容器虚拟机
    SSH 无法启动的原因分析及解决方法
    Azure 经典模式中虚拟机证书指纹的生成和作用
    远程桌面到 Ubuntu 虚拟机
    Azure Linux 虚拟机常见导致无法远程的操作
    Azure Linux 虚机上配置 RAID 的常见问题及解决方案
    使用 Azure CLI 在 Azure China Cloud 云平台上手动部署一套 Cloud Foundry
    数据库设计(六)第二范式(2NF)?
  • 原文地址:https://www.cnblogs.com/c-lover/p/11381169.html
Copyright © 2011-2022 走看看