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

开篇三问

  • 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,调用父类的构造函数,然后初始化子类。

    感觉这部分逻辑有问题。。。。。。

实列+JVM讲解类的实列化顺序的更多相关文章

  1. mybatis高级(2)_数据库中的列和实体类不匹配时的两种解决方法_模糊查询_智能标签

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...

  2. SQLite帮助类SQlitehelper 实现对SQLite数据的增删改查

    public class SQLiteHelper { public const string sConn = "Data Source=" + @"path" ...

  3. 【优化】COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主键)、COUNT(ROWID)、COUNT(非空列)、COUNT(允许为空列)、COUNT(DISTINCT 列名)

    [优化]COUNT(1).COUNT(*).COUNT(常量).COUNT(主键).COUNT(ROWID).COUNT(非空列).COUNT(允许为空列).COUNT(DISTINCT 列名) 1. ...

  4. 在论坛中出现的比较难的sql问题:6(动态行转列 考试科目、排名动态列问题)

    原文:在论坛中出现的比较难的sql问题:6(动态行转列 考试科目.排名动态列问题) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路. 下面的几个问题,都是动态行转列的问题. ...

  5. pandas.DataFrame对行和列求和及添加新行和列

    导入模块: from pandas import DataFrame import pandas as pd import numpy as np 生成DataFrame数据 df = DataFra ...

  6. WPF DataGrid某列使用多绑定后该列排序失效,列上加入 SortMemberPath 设置即可.

    WPF DataGrid某列使用多绑定后该列排序失效 2011-07-14 10:59hdongq | 浏览 1031 次  悬赏:20 在wpf的datagrid中某一列使用了多绑定,但是该列排序失 ...

  7. JVM查找类文件的顺序(转)

    配置classpath 根据path环境变量的原理,可以定义一个名为classpath环境变量,将要运行的class文件所在目录定义在该变量中. 例:set classpath=c:\ classpa ...

  8. jqm的多列布局demo,html5的多列布局demo,多列布局的具体解说,html5开发实例具体解释

    因为移动设备屏幕宽度较小,所以一般不建议使用多列布局.但有时你可能须要并排放置一些元素(如button之类的). jQuery Mobile通过约定的类名ui-grid来提供了一种基于css的多列布局 ...

  9. SQLServer2016 之后增加了索引列数的限制 从 16个列 增加到了 32个列

    创建带有包含列的索引 https://docs.microsoft.com/zh-cn/sql/relational-databases/indexes/create-indexes-with-inc ...

随机推荐

  1. linux 上配置swoole

    1.首先我们要安装swoole扩展的话,需要把它的包下载下来,下载地址是: https://github.com/swoole/swoole-src 本人qq群也有许多的技术文档,希望可以为你提供一些 ...

  2. mongdb 学习

    一:安装1.首先到官网(http://www.mongodb.org/downloads )下载合适的安装包2.安装mongodb3. cmd 命令切换到安装目录bin 下面 mongod --dbp ...

  3. 对npm的认识

    npm由三个不同的组件组成:1,网站 2.命令行界面(CLI)3.注册表 需要在网站注册 命令行界面用来进行交互 注册表来进行保存 安装本地软件包 npm install 包名 更新本地软件包 npm ...

  4. CDMA与OFDM之技术比较

    频谱利用率.支持高速率多媒体服务.系统容量.抗多径信道干扰等因素是目前大多数固定宽带无线接入设备商在选择CDMA(码分多址)或OFDM(正交 频分复用)作为点到多点(PMP)的关键技术时的主要出发点. ...

  5. 五年双十一:SLS数据管道发展之路

    日志服务SLS是一款飞天团队自研产品,服务云上云下3W+客户,并在阿里经济体中作为日志数据的基础设施,在过去几年中经历多次双十一.双十二.新春红包锤炼.在2019双十一中: 服务阿里经济体3W+ 应用 ...

  6. Linux内核设计与实现 总结笔记(第十二章)内存管理

    内核里的内存分配不像其他地方分配内存那么容易,内核的内存分配不能简单便捷的使用,分配机制也不能太复杂. 一.页 内核把页作为内存管理的基本单位,尽管处理器最小寻址坑是是字或者字节.但是内存管理单元MM ...

  7. 解决:未能加载文件或程序集“MiniProfiler”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配

    参考:https://www.lanhusoft.com/Article/120.html 产生的原因: 公司原来的项目用的是MiniProfiler 3.0.11新项目本来想使用4.0,但是无奈网上 ...

  8. 滑动报 Unable to preventDefault inside passive event listener due to target being treated as passive 的解决方法

    google浏览器滑动出现以下问题: 解决办法如下:在html元素下添加样式 touch-action: none; html{ touch-action:none; }

  9. 8 Django模型层(1)

    知识预览 ore简介 单表操作 章节作业 ore简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可 ...

  10. TimeUtils

    public class TimeUtils { public static final int YEAR = 0; public static final int MONTH = 1; public ...