自定義類加載器,發現會自動加載類和類的父類一直加載到java.lang.object爲止

下面是自定義加載器的實現

package com.ggp.jvm;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author: ggp
 * @Date: 2019/4/24 08:46
 * @Description:
 */
public class ClassLoaderTest {
    public static void main(String[] args) throws Exception {
        ClassLoader myLoader = new ClassLoader() {

            @Override
            public Class<?> loadClass(String name)throws ClassNotFoundException{
                try{
                    String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
                    /**
                     * 本類的同路徑下
                     */
                    InputStream is = this.getClass().getResourceAsStream(fileName);
                    /**
                     * 如果未找到class文件,就調用父類的loadClass();
                     */
                    if(is == null){
                        System.out.println("********super加載***********");
                        return super.loadClass(name);
                    }
                    System.out.println("********this加載***********");
                    byte[] b = new byte[is.available()];
                    is.read(b);
                    /**
                     * 生成class對象
                     */
                    return defineClass(name,b,0,b.length);
                }catch(IOException e){
                    throw new ClassNotFoundException(name);
                }
            }
        };
       myLoader.loadClass("com.ggp.jvm.ClassLoaderTest");

    }
}

打印結果

********this加載***********
********super加載***********

按理來說應該只加載一次纔對

我打了斷點追了了代碼,一直到

通過native可以判斷這是個本地方法。然後就又再次調用了loadClass()這個方法

第一次正確加載com.ggp.jvm.ClassLoaderTest這個類

但是加載完成後又再次調用了這個類加載器,並且加載的是java.lang.object這個類

想到java.lang.object是所有類的父類,猜想會不會是類加載的時候也把他的父類加載了

更改代碼驗證猜想

package com.ggp.jvm;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author: ggp
 * @Date: 2019/4/24 08:46
 * @Description:
 */
public class ClassLoaderTest {
    public static void main(String[] args) throws Exception {
        ClassLoader myLoader = new ClassLoader() {

            @Override
            public Class<?> loadClass(String name)throws ClassNotFoundException{
                try{
                    System.out.println(name);
                    String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
                    /**
                     * 本類的同路徑下
                     */
                    InputStream is = this.getClass().getResourceAsStream(fileName);
                    /**
                     * 如果未找到class文件,就調用父類的loadClass();
                     */
                    if(is == null){
                        System.out.println("********super加載***********");
                        return super.loadClass(name);
                    }
                    System.out.println("********this加載***********");
                    byte[] b = new byte[is.available()];
                    is.read(b);
                    /**
                     * 生成class對象
                     */
                    return defineClass(name,b,0,b.length);
                }catch(IOException e){
                    throw new ClassNotFoundException(name);
                }
            }
        };
       myLoader.loadClass("com.ggp.jvm.Son");

    }
}

打印結果

com.ggp.jvm.Son
********this加載***********
com.ggp.jvm.Dad
********this加載***********
java.lang.Object
********super加載***********

Process finished with exit code 0

猜想正確

說明類加載器會通過 defineclass1這個本地方法加載父類

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章