前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Class.forName与ClassLoader的区别

Class.forName与ClassLoader的区别

作者头像
用户5546570
发布2020-12-07 10:42:44
3080
发布2020-12-07 10:42:44
举报

前言

今天看Java代理的一些文章的时候,通过动态代理想到了反射的问题,然后就想到了以前面试的时候被问到的一个面试问题: Class.forName与ClassLoader的区别? ,自己当时虽然回答上来了,但是回答的并不具体,今天有空做个整理。

在Java中Class.forName()和ClassLoader都是对类进行加载,我们也知道在Class.forName中会加载静态代码块,但是ClassLoader并不会加载静态代码块。

从以上我们也可以推出来,其实ClassLoader是遵循了双亲委派模型,最终会调用类加载器来加载,它的功能是 通过一个类的类名来获取该类的二进制字节流 , 然后将该字节流放入到JVM中 。 我们可以查看Class.forName的源码:

代码语言:javascript
复制
@CallerSensitive
public static Class<?> forName(String className)
            throws ClassNotFoundException {
    Class<?> caller = Reflection.getCallerClass();
    return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}

在以上的源码中可以看到最终是调用forName0这个方法,这个方法中有四个参数:

第一个参数:类名 第二个参数:是否对类进行初始化,设置为true,则会执行类中的静态代码块 第三个参数:第三个参数是设定类加载器 因此我们可以使用 Class.forName(String name, boolean initialize,ClassLoader loader) ,来自己设定是否进行初始化以及类加载器。

对于ClassLoader来说,Java中有三种ClassLoader,分别是:

代码语言:javascript
复制
BootstrapClassLoader
ExtClassLoader
AppClassLoader
而在ClassLoader源码中,主要是这 三种类加载器通过类的路径来加载该类生成二进制字节流放入JVM中 。

/*
     * The class loader used for loading installed extensions.
     */
    static class ExtClassLoader extends URLClassLoader {
 
        static {
            ClassLoader.registerAsParallelCapable();
        }
 
        /**
         * create an ExtClassLoader. The ExtClassLoader is created
         * within a context that limits which files it can read
         */
        public static ExtClassLoader getExtClassLoader() throws IOException
        {
            final File[] dirs = getExtDirs();
 
            try {
                // Prior implementations of this doPrivileged() block supplied
                // aa synthesized ACC via a call to the private method
                // ExtClassLoader.getContext().
 
                return AccessController.doPrivileged(
                    new PrivilegedExceptionAction<ExtClassLoader>() {
                        public ExtClassLoader run() throws IOException {
                            int len = dirs.length;
                            for (int i = 0; i < len; i++) {
                                MetaIndex.registerDirectory(dirs[i]);
                            }
                            return new ExtClassLoader(dirs);
                        }
                    });
            } catch (java.security.PrivilegedActionException e) {
                throw (IOException) e.getException();
            }
        }
 
        private static File[] getExtDirs() {
            String s = System.getProperty("java.ext.dirs");
            File[] dirs;
            if (s != null) {
                StringTokenizer st =
                    new StringTokenizer(s, File.pathSeparator);
                int count = st.countTokens();
                dirs = new File[count];
                for (int i = 0; i < count; i++) {
                    dirs[i] = new File(st.nextToken());
                }
            } else {
                dirs = new File[0];
            }
            return dirs;
        }

......
    }

那么哪些地方使用到了Class.forName或者ClassLoader呢?

在进行JDBC连接时,我们通常使用Class.forName去实现。 在Spring中的IOC使用ClassLoader。 以上就是对Class.forName以及ClassLoader的整理!!

来源:https://www.tuicool.com/articles/aQ3M7bn

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档