2、類加載器與類初始化深度剖析

    

Demo01:

編寫代碼以下:java

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

}

 

代碼執行結果:dom

  3spa

 

Demo02:

而後將FinalTest 類中的  public static final x = 3    中的final 去掉  改爲 public satic in x = 3  3d

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

}

執行結果以下:code

  FinalTest static block!
  3blog

 

Demo03:

而後再將 FinalTest 中的成員變量  public static final int x = 3  ,改爲 public static final int x = new Random().nextInt(3);ssl

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

}

代碼執行結果以下:get

 

  FinalTest static block!
  1io

 

 

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

相關文章
相關標籤/搜索