前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >二、类加载器与类初始化深度剖析

二、类加载器与类初始化深度剖析

作者头像
梅花
发布2020-09-28 10:52:15
3170
发布2020-09-28 10:52:15
举报

Demo01:

编写代码如下:

代码语言:javascript
复制
package com.zuoyan.classloader;

class FinalTest{
    public static final  int x = 3;
    static {
        System.out.println("FinalTest static block!");
    }
}
public class MyTest01 {

    public static void main(String[] args) {
        System.out.println(FinalTest.x);
    }

}

代码执行结果:

  3

Demo02:

然后将FinalTest 类中的 public static final x = 3 中的final 去掉 改成 public satic in x = 3

代码语言:javascript
复制
package com.zuoyan.classloader;

class FinalTest{
    public static  int x = 3;
    static {
        System.out.println("FinalTest static block!");
    }
}
public class MyTest01 {

    public static void main(String[] args) {
        System.out.println(FinalTest.x);
    }

}

执行结果如下:

  FinalTest static block!   3

Demo03:

然后再将 FinalTest 中的成员变量 public static final int x = 3 ,改成 public static final int x = new Random().nextInt(3);

代码语言:javascript
复制
package com.zuoyan.classloader;

import java.util.Random;

class FinalTest{
    public static final int x = new Random().nextInt(3);
    static {
        System.out.println("FinalTest static block!");
    }
}
public class MyTest01 {

    public static void main(String[] args) {
        System.out.println(FinalTest.x);
    }

}

代码执行结果如下:

  FinalTest static block!   1

Demo01 的执行结果是 3 ,没有输出静态代码块中的内容,就代表静态代码块没有被执行,也就是说类没有被初始化,如果类被初始化了,静态代码块是一定会执行的。

    原因是: 本身 x 是 一个编译期的常量,3 在编译之后就会放在MyTest01 的常量池中,所以编译完后,MyTest01 和 FinalTest之间就没有任何关系了,删除FinalTest.class 没有任何关系

Demo02 的执行结果的原因是 : x 不是一个成员变量,需要加载类,所需需要初始化类

Demo03 结果出现的原因是: x 是一个成员变量,但是他的数值实在运行期才能确定的,所以需要加载FinalTest类

Demo04:

 代码如下,请判断代码的执行结果

代码语言:javascript
复制
package com.zuoyan.classloader;

class Parent{
    static int a = 3;
    static {
        System.out.println("Parent static block");
    }
}

class Child extends Parent{

    static int b = 4;
    static {
        System.out.println("Child static block");
    }

}

public class MyTest02 {
    
    static {
        System.out.println("MyTest9 static block");
    }
    
    public static void main(String[] args) {
        System.out.println(Child.b);
    }
}

  代码的执行结果如下:  

  MyTest9 static block   Parent static block   Child static block   4

出现这样结果的原因: 首先初始化 Main 方法所在类,然后这类调用了 Child类的成员变量,导致了Child类的初始化,一个类的初始化首先会初始化他的父类,然后初始化他的子类

  可用通过运行时 添加JVM参数来查看类的加载

  程序执行输出的结果:

  Demo05:

代码语言:javascript
复制
package com.zuoyan.classloader;

class Parent2{
    static  int a = 3;
    static {
        System.out.println("Parent2 static block");
    }
}

class Child2 extends Parent2{
    static int b = 4;
    static {
        System.out.println("Child 2 static block");
    }
}
public class MyTest03 {

    static{
        System.out.println("MyTest03 static block ");
    }

    public static void main(String[] args) {
        Parent2 parent;
        System.out.println("-----------------");
        parent = new Parent2();
        System.out.println("-----------------");
        System.out.println(parent.a);
        System.out.println("-----------------");
        System.out.println(Child2.b);
    }
}

程序执行的结果:

  MyTest03 static block   -----------------   Parent2 static block   -----------------   3   -----------------   Child 2 static block   4

  Demo06:

代码语言:javascript
复制
package com.zuoyan.classloader;

class Parent3{
    static int a =3;
    static {
        System.out.println("Parent3 static block");
    }

    static void doSomething(){
        System.out.println("do something");
    }
}


class Child3 extends Parent3{
    static{
        System.out.println("Child3 static block");
    }
}
public class MyTest04 {

    public static void main(String[] args) {
        System.out.println(Child3.a);
        Child3.doSomething();
    }


}

  程序执行出来的结果:

代码语言:javascript
复制
Parent3 static block
3
do something

  注意: a 本身是定义在父类中,我虽然通过子类来访问父类的成员变量,但是在本质上,是对于父类的主动使用,换句话说,就是成员变量定义在哪就是对谁的主动使用 (谁拥有就是对谁的主动使用)。

代码语言:javascript
复制
package com.zuoyan.classloader;
class CL{
    static {
        System.out.println("Class CL");
    }
}

public class MyTest05 {


    public static void main(String[] args) throws Exception {
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        Class<?> clazz = systemClassLoader.loadClass("com.zuoyan.classloader.MyTest05");
        System.out.println(clazz);
        System.out.println("----------------------");
        clazz = Class.forName("com.zuoyan.classloader.CL");
        System.out.println(clazz);


    }

}

执行结果:

  class com.zuoyan.classloader.MyTest05   ----------------------   Class CL   class com.zuoyan.classloader.CL

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-07-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Demo01:
  • Demo02:
  • Demo03:
  • Demo04:
  •   Demo05:
  •   Demo06:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档