搞清楚两者之间区别前,我们来了解下类加载过程。
  
  一、类加载过程
  
  1、加载
  
  通过一个类的全限定名来获取定义此类的二进制字节流。
  
  将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  
  在内存中生成一个代表这个类的Java.lang.class对象,作为方法区这个类的各种数据的访问入口。
  
  2、验证
  
  文件格式验证
  
  元数据验证
  
  字节码验证
  
  符号引用验证
  
  3、准备
  
  准备阶段是正式为类变量(仅被static修饰的变量)分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。注意,这里所说的初始值“通常情况”下是数据类型的零值,“特殊情况”下是初始化真实的值,即常量值(static final)。
  
  4、解析
  
  解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。注意,这个阶段不一定要有。
  
  5、初始化
  
  类初始化阶段是类加载过程的最后一步,真正开始执行类中定义的Java程序代码。初始化类中的所有类变量的赋值和静态语句块。
  
  有空可以看看《【JVM基础知识】java类加载机制》
  
  二、源码分析
  
  1、JDK8中Class.forName()源码
  
  @CallerSensitive
  
  public static Class<?> forName(String className)
  
  throws ClassNotFoundException {
  
  Class<?> caller = Reflection.getCallerClass(www.yongshiyule178.com);
  
  return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
  
  }
  
  @CallerSensitive
  
  public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
  
  throws ClassNotFoundException
  
  {
  
  Class<?> caller = null;
  
  SecurityManager sm = System.getSecurityManager();
  
  if (sm != null) {
  
  // Reflective call to get caller class is only needed if a security manager
  
  // is present. Avoid the overhead of making this call otherwise.
  
  caller = Reflection.getCallerClass();
  
  if (sun.misc.VM.isSystemDomainLoader(loader)) {
  
  ClassLoader ccl www.hengtongyoule.com= ClassLoader.getClassLoader(caller);
  
  if (!sun.misc.VM.isSystemDomainLoader(www.gaozhuoyiqi.com)) {
  
  sm.checkPermission(
  
  SecurityConstants.GET_CLASSLOADER_PERMISSION);
  
  }
  
  }
  
  }
  
  return forName0(name, initialize, loader, caller);
  
  }
  
  Class.forName(className)方法,内部实际调用的方法是forName0这个方法,在这个forName0方法中的第二个参数被默认设置为了true,这个参数代表是否对加载的类进行初始化,设置为true时会类进行初始化,代表会执行类中的静态代码块,以及对静态变量的赋值等操作。
  
  当然,可以通过Class.forName(String name, boolean initialize,ClassLoader loader)方法来手动选择在加载类的时候是否要对类进行初始化。
  
  2、JDK8中ClassLoader.loadClass()源码
  
  public Class<?> loadClass(String name) throws ClassNotFoundException {
  
  return loadClass(name,www.huarenyl.cn false);
  
  }
  
  ClassLoader.loadClass(className)方法,内部实际调用的方法是loadClass(name, false);
  
  第2个 boolean参数,表示目标对象是否进行链接,false表示不进行链接,即不进行包括初始化等一些列步骤,那么静态块和静态对象就不会得到执行。
  
  3、结论
  
  所以Class.forName加载类是将类进了初始化,而ClassLoader的loadClass并没有对类进行初始化,只是把类加载到了虚拟机中。
  
  三、应用场景
  
  1、JDBC时通常是使用Class.forName()方法来加载数据库连接驱动。因为在JDBC规范中明确要求Driver(数据库驱动)类必须向DriverManager注册自己,而注册的操作都在静态代码块中。
  
  2、Spring框架中的IOC的实现就是使用的ClassLoader。
  
  参考
  
  反射中Class.forName()和ClassLoader.loadClass()的区别
  
  在Java的反射中,Class.forName和ClassLoader的区别

反射中Class.forName()和classLoader的区别的更多相关文章

  1. Java反射中Class.forName和classloader的区别

    Java中Class.forName和classloader都可以用来对类进行加载. Class.forName除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块 ...

  2. 反射中Class.forName()和ClassLoader.loadClass()的区别

    一 Java类装载过程 装载:通过累的全限定名获取二进制字节流,将二进制字节流转换成方法区中的运行时数据结构,在内存中生成Java.lang.class对象: 链接:执行下面的校验.准备和解析步骤,其 ...

  3. 在Java的反射中,Class.forName和ClassLoader的区别

    前言 最近在面试过程中有被问到,在Java反射中Class.forName()加载类和使用ClassLoader加载类的区别.当时没有想出来后来自己研究了一下就写下来记录一下. 解释 在java中Cl ...

  4. 反射中,Class.forName 和 classloader 的区别

    https://blog.csdn.net/qq_27093465/article/details/52262340 java中class.forName()和classLoader都可用来对类进行加 ...

  5. 在 Java 的反射中,Class.forName 和 ClassLoader 的区别

    1. 解释 在java中Class.forName()和ClassLoader都可以对类进行加载.ClassLoader就是遵循双亲委派模型最终调用启动类加载器的类加载器,实现的功能是“通过一个类的全 ...

  6. Class.forName和ClassLoader的区别

    一 看名字就知道了,一个是类的创建,一个类加载器 二 再看下Class.forName源码,调用了ClassLoader @CallerSensitive public static Class< ...

  7. class.forName 和 classLoader的区别

    Java中的Class.forName()和ClassLoader都可以用来对类进行加载.Class.forName()除了将类的.class文件加载到JVM中 还会对类进行解释,执行类中的stati ...

  8. class.forName() 和 classLoader 的区别

    相同点:        java中class.forName() 和 classLoader 都可用来对类进行加载 不同店:        1.class.forName()除了将类的 .class ...

  9. java反射中,Class.forName和classloader的区别

    http://blog.csdn.net/qq_27093465/article/details/52262340

随机推荐

  1. Redis集群之Jedis的使用

    maven依赖 <!-- Redis客户端 --> <dependency> <groupId>redis.clients</groupId> < ...

  2. 如何命名Java变量

    如同酒店会给每个房间起个性化的名字一样,程序中的变量也需要用合理的名字进行管理--变量名! 需要注意,给酒店房间起名字时可以是数字,如“802”,也可以是有趣的名字,如“牡丹”.“美国总统”.“水帘洞 ...

  3. maven用框架编写网页运行出现HTTP Status 500 - Unable to compile class for JSP

    利用maven整合框架的时候,通过浏览器访问时,如果出现  HTTP 500-Unable to compile class for JSP 的错误,应该怎么解决呢? 之前在网上看了好多人的解决方案. ...

  4. K3 WISE安全认证方式

    k/3中间层注册三种安全认证方式: 交互式用户方式,网络服务方式,信任方式,是指组件服务中生成的COM+应用程序中的组件包的运行账户(注册中间层后产生很多ebo开头的和kdsvrmgr组件包). 三种 ...

  5. 4.请介绍一下c++和Java的区别

    1.指针 2.c++多重继承,Java只能继承一个父类,但是可以继承多个接口 3.数据类型及类,Java完全面向对象,所有函数和变量都必须是类的一部分.而c++允许将函数和变量定义为全局,Java取消 ...

  6. 牛客练习赛13D 幸运数字4

    题目链接:https://ac.nowcoder.com/acm/contest/70/D 题目大意: 略 分析: 注意到12! < 10^9 < 13!,于是当n > 13时,第k ...

  7. 安装 Tesserocr (填坑)

    参考: https://www.imooc.com/article/45278?block_id=tuijian_wz

  8. python数据结构与算法第十五天【二叉树】

    1.树的特点 (1)每个节点有零个或多个子节点: (2)没有父节点的节点称为根节点: (3)每一个非根节点有且只有一个父节点: (4)除了根节点外,每个子节点可以分为多个不相交的子树: 2.树的种类 ...

  9. 在Mac 系统上使用MAMP搭建PHP开发环境

    1.下载MAMP套件 下载地址为https://www.mamp.info/en/ 2.安装此.dmg文件 3.配置apache虚拟主机 (1)在/Applications/MAMP/conf/apa ...

  10. PHP金额工具类之将阿利伯数字转换为大写中文数字

    1.将阿拉伯数字转换为中文大写数字 <?php namespace core\components; class PriceHelper extends \yii\base\Component{ ...