java反射机制中class.forName和classloader的区别

一、类加载机制

上面两种加载类的方式说到底还是为了加载一个java类,因此需要先对类加载的过程进行一个简单的了解。我们写好的程序,然后run运行,过程可以直接看下面这张图:

往细了看大致分为5个阶段:

(1)加载:java类运行时候会生成一个class字节码文件,加载的过程就是去我们的操作系统寻找这个class文件。

(2)链接:这个过程就是把class文件加载到java虚拟机。

(3)初始化:在虚拟机中根据class文件进行初始化。

(4)使用:这个过程大家都明白。

(5)卸载:使用完了,java虚拟机进行清理。

对于class.forName和classloader来说针对的就是第一个过程,也就是加载过程。不过这俩虽然有一定的相似性,但是区别还是挺大的。

二、使用举例

我们使用代码,先看看如何使用。注意包的范围,避免加载不了。

第一步:定义User类

 

第二步:测试

 

我们在上面的test方法中,使用了两个加载方法。现在我们测试一下:

是不感觉有点区别。现在是先给出一个大体的使用,下面我们分析一下他们的区别。

三、区别

1、class.forName

class.forName()前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。注意这里的静态块指的是在类初始化时的一些数据。但是classloader却没有,想要弄清楚这个原因,还是直接到源码中看看。

在这个源码中我们会发现,其实底层真正实现的是forName0方法,那这几个参数又是什么意思呢?

(1)className:表示我们要加载的类名

(2)true:指Class被加载后是不是必须被初始化。 不初始化就是不执行static的代码即静态代码,在这里默认为true,也就是默认实现类的初始化。

(3)ClassLoader.getClassLoader(caller):表示类加载器,到这你会发现forNanme其实也是使用的ClassLoader类加载器加载的。

(4)caller:指定类加载器。

所以,在这里你可以指定是否在class加载后被初始化。而且底层还是使用的classloader加载的。

2、classloader

在上面的案例中我们发现,classloader并没有初始化静态块,原因最好还是到源码中看。

首先我们先进入到loadclass方法中的源码。

public Class<?> loadClass(String name)

throws ClassNotFoundException {

return loadClass(name, false);

}

这一步看起来还看不明白,没关系这里真正实现的是内部的loadclass,我们再跟进去看看。

这个才是真正实现的方法,在这里的步骤其实很简单,大致流程是先判断class是否已经被加载,如果被加载了那就重新加载,如果没有加载那就使用双亲委派原则加载。加载的时候并没有指定是否要进行初始化。

所以现在他们的区别基本上很少,总结一下:

(1)class.forName()除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。当然还可以指定是否执行静态块。

(2)classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Class.forName() 方法是 Java 反射机制的一个方法,用于动态加载类。通过该方法可以在运行时加载指定的类,返回该类的 Class 对象。它通常用于加载数据库驱动程序或其他需要动态加载的类。例如,如果要加载名为 "com.example.MyClass" 的类,可以使用以下代码: ```java Class.forName("com.example.MyClass"); ``` 这将返回一个 Class 对象,可以用于创建该类的实例或访问其静态成员。 ### 回答2: Class.forName()是Java的一个静态方法,用于加载并返回指定类名的类对象。它的主要作用是动态地加载类,可以在运行时根据需要动态加载指定的类,而不需要在编译时就确定加载的类。 具体来说,Class.forName()方法的作用包括两个方面: 1. 加载类:Class.forName()方法会根据指定的类名来加载对应的类。它会在类路径下搜索并加载指定的类文件,将类的字节码加载到内存,并返回一个Class对象,表示该类在内存的表示。 2. 初始化类:在类加载过程Class.forName()方法会自动初始化被加载类的静态代码块和静态变量。该过程会执行被加载类的静态初始化代码,为类的静态变量分配内存空间,并为其赋予初始值。 需要注意的是,Class.forName()方法可以加载任意类型的类,包括普通的类、接口、抽象类,甚至是数组类。当指定的类名无法找到或加载时,该方法会抛出ClassNotFoundException异常。 Class.forName()方法常用于反射、数据库操作和框架开发等领域。在反射,该方法可以根据类名动态地创建和操作对象;在数据库操作,该方法可以加载数据库驱动程序,使得程序可以与数据库进行交互;在框架开发,该方法可以根据配置文件等动态加载不同的实现类。 总之,Class.forName()方法是Java一个重要的用于动态加载类的方法,能够在运行时加载指定的类,并对其进行初始化。它为Java的灵活性和动态性提供了重要的支持。 ### 回答3: Class.forName()是Java语言的一个方法,用于加载并返回指定类名的Class对象。 在Java程序,当我们需要使用一个类时,需要先加载这个类的Class对象。Class.forName()方法可以实现动态加载类,即在程序运行时才加载指定的类。通过这个方法,我们可以根据类的名称获取对应的Class对象,然后再通过Class对象进行一系列的操作,例如实例化对象、调用方法等。 Class.forName()方法的具体使用方式为:Class.forName("类的全限定名")。调用这个方法时,它会将指定的类名传递给ClassLoaderClassLoader会根据类名去搜索并加载类的字节码文件,最终返回对应的Class对象。 Class.forName()方法常用在需要在运行时动态加载类的场景,例如使用反射机制时。通过Class.forName()方法,我们可以在运行时根据需要动态加载类,从而达到灵活使用不同的类的目的。另外,这个方法在一些框架也常被使用,用于实现插件化、模块化等特性。 需要注意的是,Class.forName()方法会触发类的初始化操作,即执行类的静态代码块和静态成员变量的初始化。如果只是希望加载类而不执行初始化操作,可以使用ClassLoader的loadClass()方法替代Class.forName()方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值