Java类初始化执行流程解析

网友投稿 277 2023-01-18

Java类初始化执行流程解析

测试代码:

package com.test.ClassLaoderTest;

public class test1 {

public static String s_variable = "静态变量";

public String init_variable = "公开的变量";

private String p_variable = "私有的变量";

//静态代码块

static {

System.out.println(s_variable);

System.out.println("静态代码块初始化执行了");

}

//初始化代码块

{

System.out.println(init_variable);

System.out.println(p_variable);

System.out.println("初始化代码块执行沦");

}

//构造方法

public test1(){

System.out.println("我是构造方法");

}

public static void main(String[] args) {

}

}

直接运行:

main方法里面不做任何调用的情况下,自动调用的是静态代码块和静态变量

(2)调用静态变量和静态方法:

测试代码:

package com.test.ClassLaoderTest;

public class test1 {

public static String s_variable = "静态变量";

public String init_variable = "公开的变量";

private String p_variable = "私有的变量";

//静态代码块

static {

System.out.println(s_variable);

System.out.println("静态代码块初始化执行了");

}

//初始化代码块

{

System.out.println(init_variable);

System.out.println(p_variable);

System.out.println("初始化代码块执行沦");

}

//构造方法

public test1(){

System.out.println("我是构造方法");

}

//静态方法

public static void test1(){

System.out.println("这是静态方法");

}

public static void main(String[] args) {

System.out.println(test1.s_variable);

test1.test1();

}

}

运行:

结论:当我调用静态方法/静态变量时,只会家在静态代码块,其余的代码块/构造方法不会被加载

(3)创建对象:

package com.test.ClassLaoderTest;

public class test1 {

public static String s_variable = "静态变量";

public String init_variable = "公开的变量";

private String p_variable = "私有的变量";

//静态代码块

static {

System.out.println(s_variable);

System.out.println("静态代码块初始化执行了");

}

//初始化代码块

{

System.out.println(init_variable);

System.out.println(p_variable);

System.out.println("初始化代码块执行了");

}

//构造方法

public test1(){

System.out.println("我是构造方法");

}

//静态方法

public static void test1(){

System.out.println("这是静态方法");

}

public static void main(String[] args) {

test1 t1 = new test1();

}

}

运行结果:

输出内容:

静态变量

静态代码块初始化执行了

公开的变量

私有的变量

初始化代码块执行了

我是构造方法

结论:当创建对象/实例化的时候,调用顺序:静态代码块->初始化代码->构造方法,最后执行的才是构造方法

(4)有继承关系下的类初始化执行流程:

环境:

父类:

package com.test.ClassLaoderTest;

public class father {

public static String s_variable = "父类静态变量";

public String init_variable = "父类公开的变量";

private String p_variable = "父类私有的变量";

//父类静态代码块

static {

System.out.println(s_variable);

System.out.println("父类静态代码块初始化执行了");

}

//父类初始化代码块

{

System.out.println(init_variable);

System.out.println(p_variable);

System.out.println("父类初始化代码块执行了");

}

//构造方法

public father(){

System.out.println("我是父类构造方法");

}

//父类静态方法

public static void test1(){

System.out.println("这是父类静态方法");

}

}

test1.java:

继承其父类father:

package com.test.ClassLaoderTest;

public class test1 extends father{

public static String s_variable = "子类静态变量";

public String init_variable = "子类公开的变量";

private String p_variable = "子类私有的变量";

//子类静态代码块

static {

System.out.println(s_variable);

System.out.println("子类静态代码块初始化执行了");

}

//子类初始化代码块

{

System.out.println(init_variable);

System.out.println(p_variable);

System.out.println("子类初始化代码块执行了");

}

//子类构造方法

public test1(){

System.out.println("我是子类构造方法");

}

//子类静态方法

public static void test1(){

System.out.println("这是子类静态方法");

}

public static void main(String[] args) {

}

}

main方法不做任何操作,运行:

只要extends继承了,优先调用父类静态代码块

(5)有继承关系下的调用静态方法:

修改子类即可:

package com.test.ClassLaoderTest;

public class test1 extends father{

public static String s_variable = "子类静态变量";

public String init_variable = "子类公开的变量";

private String p_variable = "子类私有的变量";

//子类静态代码块

static {

System.out.println(s_variable);

System.out.println("子类静态代码块初始化执行了");

}

//子类初始化代码块

{

System.out.println(init_variable);

System.out.println(p_variable);

System.out.println("子类初始化代码块执行了");

}

//子类构造方法

public test1(){

System.out.println("我是子类构造方法");

}

//子类静态方法

public static void test1(){

System.out.println("这是子类静态方法");

}

public static void main(String[] args) {

test1.test1();

father.test1();

}

}

运行:

结果:

父类静态变量

父类静态代码块初始化执行了

子类静态变量

子类静态代码块初始化执行了

这是子类静态方法

这是父类静态方法

main方法中,谁优先调用静态方法,就优先加载谁

(6)有继承关系下的创建对象:

代码:

package com.test.ClassLaoderTest;

public class test1 extends father{

public static String s_variable = "子类静态变量";

public String init_variable = "子类公开的变量";

private String p_variable = "子类私有的变量";

//子类静态代码块

static {

System.out.println(s_variable);

System.out.println("子类静态代码块初始化执行了");

}

//子类初始化代码块

{

System.out.println(init_variable);

System.out.println(p_variable);

System.out.println("子类初始化代码块执行了");

}

//子类构造方法

public test1(){

System.out.println("我是子类构造方法");

}

//子类静态方法

public static void test1(){

System.out.println("这是子类静态方法");

}

public static void main(String[] args) {

test1 t1 =new test1();

}

}

运行:

结果:

父类静态变量

父类静态代码块初始化执行了

子类静态变量

子类静态代码块初始化执行了

父类公开的变量

父类私有的变量

父类初始化代码块执行了

我是父类构造方法

子类公开的变量

子类私有的变量

子类初始化代码块执行了

我是子类构造方法

结论:通过结果会发现,不管是子类还是父类静态代码块,静态代码块在哪里都是爸爸级别,最先加载的,当创建test1对象的时候,优先加载的是父类代码块,那么他的初始化执行流程如下:父类静态代码块>子类静态代码块>父类初始化代码块>父类构造方法>子类代码块>子类构造方法

(7) 有继承关系下的创建父类对象:

package com.test.ClassLaoderTest;

public class test1 extends father{

public static String s_variable = "子类静态变量";

public String init_variable = "子类公开的变量";

private String p_variable = "子类私有的变量";

//子类静态代码块

static {

System.out.println(s_variable);

System.out.println("子类静态代码块初始化执行了");

}

//子类初始化代码块

{

System.out.println(init_variable);

System.out.println(p_variable);

System.out.println("子类初始化代码块执行了");

}

//子类构造方法

public test1(){

System.out.println("我是子类构造方法");

}

//子类静态方法

public static void test1(){

System.out.println("这是子类静态方法");

}

public static void main(String[] args) {

father father = new father();

}

}

运行:

结果:

父类静态变量

父类静态代码块初始化执行了

子类静态变量

子类静态代码块初始化执行了

父类公开的变量

父类私有的变量

父类初始化代码块执行了

我是父类构造方法

结论:优先执行的是两个类的静态代码块,然后是父类型的代码块和构造方法,而子类的代码块和构造方法没有被执行是因为没有实例化子类,所以肯定是没有他的,那么只有在创建对象的时候,才会调用代码块和构造方法

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot+MyBatisPlus+Vue 前后端分离项目快速搭建过程(后端)
下一篇:mybatis 为什么千万不要使用 where 1=1
相关文章

 发表评论

暂时没有评论,来抢沙发吧~