类加载过程

类加载loadClass

 验证:主要验证字节码文件,如开头cafe babe
 准备:初始化静态变量,定义常量
 解析:符号引用指向直接引用,如main方法指向jvm内存区域
 初始化:赋值静态变量,执行类的静态代码块
 类加载

思考一:

public class A {

    static {
        System.out.println(".......static test A .............");
    }
    public A() {
        System.out.println(".......public test A .............");
    }
    public static void main(String[] args) {
        new A();
        System.out.println("........main Test .............");
        B b = null;
    }
}
class B{
    static {
        System.out.println(".......static test B .............");
    }
    public B() {
        System.out.println(".............public test B............");
    }

}

类加载器种类

引导类加载器:负责加载jdk中JRE中lib下的核心内库,如rt.jar
	
扩展类加载器:负责加载jdk中JRE中lib下ext文件下的核心内库

应用类加载器:加载classpath路径下的类包,自己写的类

自定义类加载器:

思考二

 System.out.println(String.class.getClassLoader());
 System.out.println(SunEC.class.getClassLoader());
 System.out.println(User.class.getClassLoader());

类加载器初始化源码

  • 初始化Launcher类
private static Launcher launcher = new Launcher();
    private static String bootClassPath =
        System.getProperty("sun.boot.class.path");

    public static Launcher getLauncher() {
        return launcher;
    }
  • 初始化扩展类加载器
   ClassLoader extcl;
   try {
        extcl = ExtClassLoader.getExtClassLoader();
    } catch (IOException e) {
        throw new InternalError(
            "Could not create extension class loader", e);
    }
	 return AccessController.doPrivileged(
     new PrivilegedExceptionAction<ExtClassLoader>() {
         public ExtClassLoader run() throws IOException {
             final File[] dirs = getExtDirs();
             int len = dirs.length;
             for (int i = 0; i < len; i++) {
                 MetaIndex.registerDirectory(dirs[i]);
             }
             //主要new 的扩展类加载器 
             //扩展类加载器的父属性是引导类加载器
             //但引导类加载器是c/c++ 产生的,故而parent属性传null和不传一样
             return new ExtClassLoader(dirs);
         }
     });
  • 初始化应用类加载器
  //将ExtClassLoader传进来
  loader = AppClassLoader.getAppClassLoader(extcl);
	final String s = System.getProperty("java.class.path");
    final File[] path = (s == null) ? new File[0] : getClassPath(s);
	return AccessController.doPrivileged(
     new PrivilegedAction<AppClassLoader>() {
         public AppClassLoader run() {
         URL[] urls =
             (s == null) ? new URL[0] : pathToURLs(path);
          //主要new 的应用类加载器
         return new AppClassLoader(urls, extcl);
     }
 });
//调用父类将extClassLoader赋值到parent属性
 private ClassLoader(Void unused, ClassLoader parent) {
        this.parent = parent;
        if (ParallelLoaders.isRegistered(this.getClass())) {
            parallelLockMap = new ConcurrentHashMap<>();
            package2certs = new ConcurrentHashMap<>();
            assertionLock = new Object();
        } else {
            // no finer-grained lock; lock on the classloader instance
            parallelLockMap = null;
            package2certs = new Hashtable<>();
            assertionLock = this;
        }
    }

类加载双亲委派机制

//ClassLoad.class
protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            //尝试在类加载器里缓存查找是否已经加载
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                try {
                    if (parent != null) {
                    	//this类加载器缓存没有,就让父类加载
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                  
                }
                if (c == null) {
                //重要主要是类加载的过程
                    c = findClass(name);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
{
        final Class<?> result;
        try {
            result = AccessController.doPrivileged(
                new PrivilegedExceptionAction<Class<?>>() {
                    public Class<?> run() throws ClassNotFoundException {
                        String path = name.replace('.', '/').concat(".class");
                        Resource res = ucp.getResource(path, false);
                        if (res != null) {
                            try {
                            //TODO 进行类的加载过程
                                return defineClass(name, res);
                            } catch (IOException e) {
                                throw new ClassNotFoundException(name, e);
                            }
                        } else {
                            return null;
                        }
                    }
                }, acc);
        } catch (java.security.PrivilegedActionException pae) {
            throw (ClassNotFoundException) pae.getException();
        }
        if (result == null) {
            throw new ClassNotFoundException(name);
        }
        return result;
    }

自定义类加载器-主要是重写findClass

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
    	//name: 类
       String newName = name.replaceAll("\\.", "/");
       FileInputStream fileInputStream = null;
       byte[] bytes = null;
       try {
        	//path:类加载器:加载类的路径
            fileInputStream=  new FileInputStream(path+"/"+newName+".class");
            bytes = new byte[fileInputStream.available()];
            fileInputStream.read(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  defineClass(name, bytes, 0, bytes.length, null);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小阳会武功

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值