自定义类加载器,发现会自动加载类和类的父类一直加载到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为止_第1张图片

但是加载完成后又再次调用了这个类加载器,并且加载的是java.lang.object这个类

自定义类加载器,发现会自动加载类和类的父类一直加载到java.lang.object为止_第2张图片

想到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这个本地方法加载父类

你可能感兴趣的:(jvm)