加载/执行顺序:

牢记一点:

静态和非静态分开处理

使用到静态加载时,静态又分为: 静态变量, 静态代码块, 其中加载顺序是按照类中书写的先后顺序加载的

非静态加载顺序: 按照非静态书写顺序加载/执行

静态方法,实例方法只有在调用的时候才会去执行

当静态加载中遇到需要加载非静态的情况: 先加载非静态再加载静态。

下面两种情况的加载顺序

不涉及到父类子类的情况:

1) 首先将所有静态成员变量加载进来, 但是不赋值,JVM会根据属性的数据类型第一时间赋默认值

2)然互再进行赋值,即加载静态变量一一为分配内存赋值,静态变量,静态块的加载,没有优先级之分,按照书写先后顺序加载

特殊情况: 静态变量是加载类本生的实例,会比较麻烦,稍后讲解

涉及到父类的情况

父静态-->子静态  加载时不涉及构造方法,只有使用都new才会涉及到构造方法

下面将具体讲述程序执行顺序

1. main第一句是否先执行

Java程序运行时,第一件事情就是试图访问main方法,因为main相等于程序的入口,如果没有main方法,程序将无法启动,main方法更是占一个独立的线程,找到main方法后,是不是就会执行mian方法块里的第一句话呢?不是

因为main方法虽然是一个特殊的静态方法,但是还是静态方法,此时JVM会加载main方法所在的类,试图找到类中其他静态部分,即首先会找main方法所在的类。

public class JVMTest {

static{

System.out.println("Main 方法所在静态代码块 static1");

}

public static void main(String[] args) {

System.out.println("main start");

A a = new A();

System.out.println(A.width);

System.out.println(a.width);

}

static{

System.out.println("Main 方法所在静态代码块 static2");

}

}

class A{

public static int width = 100;

static{

System.out.println("静态初始化类A");

width = 30;

}

public A(){

System.out.println("创建A类的对象");

}

}

结果

Main 方法所在静态代码块 static1

Main 方法所在静态代码块 static2

main start

静态初始化类A

创建A类的对象

30

30

上例中: 先找到main方法, 然后先加载main 方法所在的类JVMTest的静态属性, 静态代码块(按照顺序加载),即使静态代码块在main方法下面也要先加载静态代码块。然后执行 main方法

2. 静态变量声明一定放在使用前面

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

son init:0

执行顺序:

1)加载Main方法, 先要加载包含Main方法的类, 加载类就先加载父类静态变量, 静态代码块(按照书写先后顺序)--》 子类静态变量,静态代码块

2) 执行main方法

3) main 方法中调用有构造函数

父类代码块--》 父类构造函数--》子类代码块--》子类构造函数

4. 一个比较复杂的例子,如果下面的例子理解了,就撤离理解了Java的执行顺序

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)JVM 类加载机制中提到,类连接 (验证, 准备, 解析)中准备工作:

负责为类的类变量(非对象变量)分配内存,并设置默认初始值,准备类中每个字段、方法和实现接口所需的数据结构, 这里说的初始值都是默认的值, 并不是程序中指定的值 , 经过准备工作,类中变量的初始值为如下

k =0; b=0; t1=null; t2=null; i=0; n=0;

2)  JVM在类连接以后进行类的初始化,即给类变量赋值,按照静态属性的书写顺序执行

A: public static int k = 10;     -->  k=10

B:public static int b = print("b");   -->调用print("b")  print:11:b   i=0    n=0

C: public static Text t1 = new Text("t1");  当加载静态变量是需要先加载构造器, 那就转为先加载所有非静态属性

此时按照书写的顺序加载非静态, 如下所示

public int a = print("a"); --》 print:12:a i=1 n=1

public int j = print("j"); --》print:13:j i=2 n=2

public int m = print("m"); --》print:14:m i=3 n=3

{

print("构造块"); --》print:15:构造块 i=4 n=4

}

public int l = print("l"); --》print:16:l i=5 n=5

public int p = print("p"); --》print:17:p i=6 n=6

然后继续执行构造器

public Text(String str) {

System.out.println("构造:" + (++k) + ":" + str + " i=" + i + " n=" + n);

++i;

++n;

}

==》构造:18:t1   i=7    n=7

D:     public static Text t2 = new Text("t2");  和C的过程一模一样, 非静态的每次new都加载一次

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

E:     public static int i = print("i");  ==>print:26:i   i=15    n=15

F:      public static int n = 99;   n=99

G:

static {

print("静态块");

}

==>print:27:静态块   i=16    n=99

H:    public static int o = print("o"); ==>print:28:o   i=17    n=100

I: Text t = new Text("init");

==>

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

参考: https://www..com/greatfish/p/5771548.html1·

Java实例化后自动执行_Java的实例化顺序(程序执行顺序)相关推荐

  1. 一个可以开机后自动和你打招呼的小程序(希望以后可以成为智能的系统)

    这是一个可以开机后自动和你打招呼的小程序,至于你的名字在配置文件中.这里主要是应用了微软的speech技术来播放声音.所以如果你有其他的需求可以自己扩展.这里我只是写了很少的一部分功能,以后有新的想法 ...

  2. Win10休眠模式设置:开机后自动恢复工作界面,防止程序员虐待电脑

    Win10休眠模式设置:开机后自动恢复工作界面,防止程序员虐待电脑 这个功能叫做休眠,与睡眠不同,休眠会在电脑关机之后,将当前工作环境保存为文件,然后在开机之后自动恢复.这个功能对不爱关机的程序员非常 ...

  3. java回车后自动从一个文本框切换到另一个_Java实用教程-Java基本语法-Java程序的构成...

    Java源程序逻辑构成分为两大部分:程序头包的引用和类的定义. 1.程序头包的引用 主要是指引用JDK软件包自带的包,也可以是自己定义的类.引用之后程序体中就可以自由应用包中的类的方法和属性等. 2. ...

  4. java向后兼容吗_Java向后不兼容历史的观察

    java向后兼容吗 在大多数情况下,Java是一个非常向后兼容的编程语言. 这样做的好处是,与大规模破坏兼容性相比,大型系统通常可以相对轻松的方式升级为使用Java的较新版本. 这样做的主要缺点是Ja ...

  5. java 调用对象的方法_JAVA调用对象方法的执行过程

    JAVA调用对象方法的执行过程: ①.编译器查看对象的声明类型和方法名.假设调用x.f(parameter),  且隐式参数x声明为C类型的对象,有可能在C对象中存在多个参数类型和参数个数不同的f的方 ...

  6. JVM原理(二)执行引擎篇(JVM程序执行流程、JIT编译器、JIT编译器优化)

    一.JVM程序执行流程 上一章我们介绍过程序执行通常分为解释执行和编译执行,而Java两种方式都采用了,下面是Java编译成字节码.动态编译和解释为机器码的过程分析: 编译器和解释器的协调工作流程: ...

  7. java继承 后的方法_Java 继承

    extends 继承 1.继承是什么,为什么继承 使用 extends 父类 子类继承父类,代码可以得到复用 使用继承机制可以做到方法的覆盖和多态机制 继承也是存在缺点的:耦合度高,父类修改,子类受牵 ...

  8. java卸载后装不_java卸载之后再重新安装之后无法运行Java了

    将Program files下的SQL安装目录删除(此处如果有重要的数据,请先备份)JAVA中文站社区门户2h*L ` U@*op1t5F C:Program FilesMicrosoft SQL S ...

  9. java string 后几位_java中String占几个位元组

    java中String占几个位元组以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! java中String占几个位元组 J ...

最新文章

  1. 谁在关心toString的性能?
  2. 【学习笔记】28、类的方法及参数介绍
  3. SAP云平台的Document Service
  4. [原创]K8 cping 3.0大型内网渗透扫描工具
  5. iOS设备控制打印机输出文本
  6. 留言板分页php,php留言板代码[经典的分页代码](1/4)
  7. 直流电机正反转驱动电路
  8. 浅谈二十年后电气工程前途
  9. Python运算(五)统计statistic模块
  10. Kmeans参数n_clusters_labels_centers_
  11. 基于SSM高校教室管理系统毕业设计-附源码181523
  12. Android 天气APP(三十六)运行到本地AS、更新项目版本依赖、去掉ButterKnife
  13. linux触摸板设置密码程序6,Linux下Synaptics笔记本触摸板的配置
  14. PT100三线制恒流源接法
  15. 【DB笔试面试755】在Oracle的DG中,RFS、LNSn、MRP、LSP进程的作用分别是什么?
  16. 如果机器可以深度学习,人类的学习有何意义
  17. Altium Designer整理和小插曲
  18. jQuery的deferred对象深析
  19. 虚拟机 硬盘空间不足 磁盘最大大小调整的相对方法
  20. Ant Design Vue 文件上传自定义按钮和文件列表位置

热门文章

  1. OpenCV与图像处理学习十——区域生长算法(含代码)
  2. 小甲鱼 OllyDbg 教程系列 (二) :从一个简单的实例来了解PE文件
  3. 轻量级分布式任务调度平台 XXL-JOB
  4. 集合对象-“块数据”操作--其实是同一对象引用
  5. C++学习之路 | PTA乙级—— 1055 集体照 (25 分)(精简)
  6. 1053 Path of Equal Weigh(甲级)
  7. pythonasyncio并发编程实战_python异步编程之asyncio(百万并发)
  8. 中科大计算机学院博士导师,中科大计算机学院招生导师
  9. android和linux操作系统的区别
  10. 搭建: canal部署与实例运行