zoukankan      html  css  js  c++  java
  • 二、类加载器与类初始化深度剖析

        

    Demo01:

    编写代码如下:

    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  

    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);

    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:

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

    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:

        

    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:

        

    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();
        }
    
    
    }

      

      程序执行出来的结果:

      

    Parent3 static block
    3
    do something

      

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

      

      

    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

  • 相关阅读:
    链表问题----反转部分单向链表
    HTTP请求详解
    链表问题----删除链表的中间节点和a/b处的节点
    链表问题----删除倒数第K个节点
    栈和队列----最大值减去最小值小于等于num的子数组的数量
    栈和队列----求最大子矩阵的大小
    TCP/IP、Http、Socket的区别
    栈和队列----生成窗口的最大值数组
    linux根文件系统制作,busybox启动流程分析
    linux 内核启动流程分析,移植
  • 原文地址:https://www.cnblogs.com/kangxinxin/p/11152785.html
Copyright © 2011-2022 走看看