类加载的顺序,便于理解的比较好的一个程序

网上的程序,自己看了一个小时,终于看明白了,感觉挺有收获

public class StaticTest {
/*main函数初始化,执行F行,先给静态变量分配内存,默认填值0;或者null(引用变量);然后给静态变量赋值;进行到第A行,给t1赋值的时候
* 要new一个对象,此时静态变量已经全部分配内存空间并默认填值0或者null了,所以这个时候第A行
* 执行初始化这个类的时候不会再给静态变量分配内存并默认填值,而是直接执行C中的普通变量的初始化,这个时候
* 调用print("j")这个方法,因为这个时候k从0自加了1,所以是1,i和n都还没有赋值,是分配内存的时候的原始值
* 0,这就是第一行的输出结果。对象实例化的时候要执行普通代码块,所以执行print("构造块"),这个时候i和n已经在
* 刚才print("j")这个方法调用的时候,自加过一次,所以现在的值为2;同理执行静态块的道理一样;执行完普通代码块,
* 才开始执行构造器方法,所以这个时候输出t1开头的值;同理,接下来的5-8条输出也是一样的道理的;
* 执行完AB之后,开始给D行的静态变量初始化,执行print"i"方法,输出i,也就是第9条的结果。然后执行E行,将99赋予n,赋予之前n的值是8!!
* 这个时候F行语句还没执行完,只执行到E这里,要接着往下执行,调用print("j"),输出第10行,然后11-12两个普通代码块
* 然后init为参数的构造方法(13行)。
*
*/
public static int k = 0;
public static StaticTest t1 = new StaticTest("t1");//A
public static StaticTest t2 = new StaticTest("t2");//B
public static int i = print("i");//D
public static int n =99;//E
public int j = print("j");//C
{
print("构造块");
}
{
print("静态块");
}
public StaticTest(String str){
System.out.println((++k)+":"+str+"i="+i+"n="+n);
++n;
++i;
}
public static int print(String str){
System.out.println((++k)+":"+str+"i="+i+"n="+n);
++i;
return ++n;
}
public static void main(String[] args) {
new StaticTest("init");//F
// StaticTest.print("123");
}

}

输出结果:

1:ji=0n=0
2:构造块i=1n=1
3:静态块i=2n=2
4:t1i=3n=3
5:ji=4n=4
6:构造块i=5n=5
7:静态块i=6n=6
8:t2i=7n=7
9:ii=8n=8
10:ji=9n=99
11:构造块i=10n=100
12:静态块i=11n=101
13:initi=12n=102

时间: 2024-08-02 04:41:54

类加载的顺序,便于理解的比较好的一个程序的相关文章

便于理解mysql内幕的各种逻辑图组

便于理解mysql内幕的各种逻辑图组 http://blog.sina.com.cn/s/blog_445e807b0101ggtl.html 以下是个人一直以来从网络等各种途径收集到的一些对理解mysql有重要意义的图,现共享给大家,共同学习,希望能够为您更好的理解mysql的各种内幕有所帮助,废话不多说,直接上图: 1,顶顶有名的官方mysql架构图,理解mysql整体机构必不可少 2,更直观性mysql整体逻辑机构图: f3,innodb引擎架构图,对理解innodb内部结构大有裨益 f

JAVA 不同类加载器命名空间的理解

            以前一直有这样一个疑惑: 都说在JAVA中,由不同类加载器加载的类在虚拟机中位于不同的命名空间下,不同命名空间下的类相互不可见. 这让我产生了一个迷惑:如果有一个类A使用了java.util.List类,为什么在运行时会没有错误.因为按照类加载的双亲委派机制,自己写的类A一般由系统类加载器加载,而java.util.List肯定是由启动类加载器(也叫Root类加载器)加载的,所以这两个类应该不在一个命名空间下.那在运行时为什么类A还 是能访问到java.util.List

Hibernate为表字段添加备注信息,便于理解数据库设计

java实体类,可以加上字段的描述,是个好的习惯吧,便于理解数据库设计,为后期维护,升级,改造提供支持

css样式加载顺序及覆盖顺序深入理解

注:内容转载 很多的新手朋友们对css样式加载顺序和覆盖顺序的理解有所偏差,下面用示例为大家详细的介绍下,感兴趣的朋友不要错过 { height: 100%; width: 200; position: absolute; left: 0; border: solid 2 #EEE; } .current_block { border: solid 2 #AE0; } 查找一些教材中(w3schools等),只说css的顺序是"元素上的style" > "文件头上的st

转载——便于理解mysql内幕的各种逻辑图组

原文地址:http://blog.sina.com.cn/s/blog_445e807b0101ggtl.html 1,顶顶有名的官方mysql架构图,理解mysql整体机构必不可少 2,更直观性mysql整体逻辑机构图: 3,innodb引擎架构图,对理解innodb内部结构大有裨益 4,mysql sql执行过程示意图,对理解mysql执行计划有很大帮助 5,当 ‘innodb_flush_log_at_trx_commit = x ’x=0,1,2 各值时刷盘时的示意图 6,mysql 内

理解 Linux shell 中的一个方言:2>&1

理解 Linux shell 中的一个方言:2>&1 2016-11-14 杜亦舒 前言 在使用 linux 命令或者 shell 编程时,这个用法常会遇到 2>&1 如果是刚开始接触Linux,这个东西的确不好理解,因为他没有直观的含义,不像一个命令,例如 cp是 copy 的简写,很好记. 我以前刚用Linux时就对这个东西迷糊了一段时间,今天刚好看到一篇文章介绍他,感觉很有必要总结出来,分享给还不是很理解这个方言的朋友. 下面看一个命令示例,然后分析下他是如何工作的: l

c程序设计 8.15写几个函数:①输个职工的姓名和职工号;②按职工号由小到大顺序排序,姓名顺序也随之调整;③要求输入一个职工号,用折半法找出该职工的姓名,从主函数输入要查找的职工号,输出该职工

8.15写几个函数:①输个职工的姓名和职工号:②按职工号由小到大顺序排序,姓名顺序也随之调整:③要求输入一个职工号,用折半法找出该职工的姓名, 从主函数输入要查找的职工号,输出该职工. 写的时候为方便输入,我设的是输入3名职工的信息. #define N 3 #include <stdio.h> #define N 3 #define LEN 20 //定义一个结构体类型 struct student{ char name[LEN]; int num; }; int main(){ int n

类加载器ClassLoader的理解

最近在做一个热加载Class的小组件,这个组件需要对类加载器ClassLoader有所了解,我就顺便借这个机会把学到的一点皮毛与大家分享一下. 从Class文件开始 ClassLoader,顾名思义就是类加载器.简单的说就是把Class文件加载到JVM中,之后程序就能正常的运行了. 我们平时写的代码都是.java格式的文件,但是这个文件是不能够直接运行的.比如下面这个简单的测试程序Test.java 1 public class Test { 2 3 public static void mai

阿里P7架构师对Java虚拟机、类加载机制是怎么理解的?

概述 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载 (Loading).验证(Verification).准备(Preparation).解析(Resolution).初始化 (Initialization).使用(Using)和卸载(Unloading)7 个阶段.其中验证.准备.解析 3 个部分统称为连接(Linking) 于初始化阶段,虚拟机规范则是严格规定了有且只有 5 种情况必须立即对类进行“初始 化”(而加载.验证.准备自然需要在此之前开始): 1)遇到