`
aids198311
  • 浏览: 59598 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Class.forName与ClassLoader

阅读更多
看了虚拟机的一些文章,有点感触,赶紧写出来。

Class 用来描述一个类型,当一个类型被装载(虚拟机读取二进制的class文件)的时候,会创建一个与该类型对应的Class对象到内存堆中。(这个时候该类型甚至没有被分配内存,设置默认值,更别说初始化了)。
Class.forName有2个重载的方法:

 public static Class<?> forName(String name, boolean initialize,
				   ClassLoader loader)
        throws ClassNotFoundException


 public static Class<?> forName(String className) 
                throws ClassNotFoundException


第一个方法:
name:类的全限定名,如:com.aaa.bbb.ccc
initialize:如果为true,则会在返回Class对象之前,对该类型做连接,校验,初始化操作。(如:执行static块中的代码)
loader:用自定义的类加载器来请求这个类型;当然,你也可以传入null,用bootstrap加载器。
第二个方法:
name和上面相同。默认initialize为true,
而loader是这么获取的
ClassLoader.getCallerClassLoader()

其实就是获取当前类的classLoader,也就是装载执行forName操作的类的classLoader

类ClassLoader包括2个重载的loadClass类
protected synchronized Class<?> loadClass(String name, boolean resolve)
	throws ClassNotFoundException

public Class<?> loadClass(String name) throws ClassNotFoundException 

两个方法都需要传name,既类的全限定名作为参数。
resolve:表示是否需要连接该类型。
注意:是连接(这里面包括校验class文件,准备分配内存,类型常量池的替换),并不会初始化该类型。

看源码可以看到,resolve也只是调用了一下resolveClass这个方法

	if (resolve) {
	    resolveClass(c);
	}


都说清楚了,也很容易区分出不同点:
1.Class.forName返回的Class对象可以决定是否初始化。而ClassLoader.loadClass返回的类型绝对不会初始化,最多只会做连接操作。
2.Class.forName可以决定由哪个classLoader来请求这个类型。而ClassLoader.loadClass是用当前的classLoader去请求。

举个例子吧:
JDBC的注册驱动大家都狠熟悉吧:
Class.forName(".......")

为啥是要用Class.forName?
首先看看注册驱动是什么意思。
打开DriverManager的代码,可以看到这个方法:
 public static synchronized void registerDriver(java.sql.Driver driver)
	throws SQLException 

如果要注册驱动,必须得这么来
DriverManager.registerDriver("......")

而这行代码,都是写在驱动的实现类,而且是一个static块来加载的。
所以随便找一个jdbc驱动程序的代码,肯定会有这样的实现
static{
.......
DriverManager.registerDriver("......")
.......
}

用来注册驱动程序到DriverManager,这样驱动才能使用。
由于static块是属于类的,所以,此处仅仅需要初始化类即可。不需要具体实例。
那么用
Class.forName(".....")

再合适不过了。
而ClassLoader由于不会初始化类。明显不行。

分享到:
评论

相关推荐

    java中Class.forName方法的作用详解

    Java中的`Class.forName()`方法是一个非常关键的工具,主要用于动态加载类。它的作用在于根据给定的类全名(包括包名)返回对应的`Class`对象。`Class`对象是Java反射机制的基础,它代表着运行时的类信息,可以通过...

    Class.forName

    下面将详细解释`Class.forName()`的工作原理、用途及其与`new`关键字的区别。 `Class.forName(String className)`方法接收一个字符串参数,这个字符串代表了类的全限定名(包括包名和类名)。当调用此方法时,JVM会...

    liuwei1989#study-guide#17-Class.forName和classloader的区别1

    并且只有调用了newInstance()方法采用调用构造函数,创建类的对象看下Class.forName()源码//Class.forName(String c

    在Java的反射中,Class.forName和Class

    `Class.forName`更方便,它内部调用了`ClassLoader.loadClass`,并且自动处理了类的初始化。而`ClassLoader`提供了更底层的控制,可以用于更复杂的类加载策略,如加载远程类、加密类等。 在使用`Class.forName`时,...

    面试题:Class.forName 和 ClassLoader 有什么区别?.docx

    图文并茂吃透面试题,看完这个,吊打面试官,拿高薪offer!

    Java 类加载机制 ClassLoader Class.forName.pdf

    2. **通过`Class.forName()`方法动态加载**:可以在运行时动态地加载类。 3. **通过`ClassLoader.loadClass()`方法动态加载**:提供了更多的灵活性,可以根据不同的需求加载不同的类。 这三种方式各有特点,具体...

    Classfor的用法

    `Class.forName` 经常与 `newInstance` 方法配合使用,以实现动态创建对象的目的。`newInstance` 方法用于创建 `Class` 对象所表示的类的实例。 **示例**: ```java try { Class&lt;?&gt; clazz = Class.forName(...

    jdbc中class.forname的作用

    4. 避免仅加载不初始化:值得注意的是,如果只是简单地使用`ClassLoader.loadClass()` 加载类,而没有实例化或执行静态初始化,那么驱动不会被注册到`DriverManager`。这样,即使类被加载到JVM中,也无法通过`...

    White paper

    ### 动态加载Java类:理解`Class.forName`与扩展区中的挑战 #### 概述 在Java开发中,动态加载类的能力是其最强大的特性之一。通过在运行时仅根据类名加载代码,而无需在编译时知道确切的类名,开发者能够构建灵活...

    jdbc--sqljdbc4-2.0.jar

    at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0...

    史上最全Java面试266题:算法+缓存+TCP+JVM+搜索+分布式+数据库.docx

    8. **Class.forName与ClassLoader**:`Class.forName()`是静态方法,通过类名加载类;ClassLoader是动态加载类的机制,可以自定义加载策略。 9. **动态代理**:Java提供了JDK动态代理和CGLIB两种实现,前者基于接口...

    hive-jdbc-1.1.0-cdh5.4.5-standalone.jar

    at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at ...

    hive-jdbc-2.1.0-standalone.jar

    at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at ...

    Java面试(2017备战)

    2. **Class.forName与ClassLoader的区别** - **Class.forName()**:这是一个静态方法,用于加载类。它会抛出`ClassNotFoundException`,如果找不到指定的类,则需要捕获异常处理。 - **ClassLoader**:`...

    Java类加载器.pdf

    - 使用`ClassLoader.loadClass(String name)`方法显式加载类。 其中,`Class.forName()`方法有两种重载形式,第一个只接受类名作为参数,第二个允许控制是否初始化类以及指定类加载器。如果只使用一个参数的`Class...

    ClassLoader(类加载机制)1

    `Class.forName()`可以初始化类的静态属性和方法,而`ClassLoader.loadClass()`则不会。例如: ```java // 显式加载 Class.forName("com.anbai.sec.classloader.TestHelloWorld"); // 自定义ClassLoader加载 ...

    面试常见知识点.docx

    ### Java反射中Class.forName与ClassLoader的区别 1. **`Class.forName`**:除了加载类的`.class`文件到JVM中之外,还会对类进行初始化,执行类中的`static`代码块。 2. **`ClassLoader`**:仅负责将`.class`文件...

    在可执行jar中载入第三方jar的几个解决方法

    这个问题通常发生在使用`Class.forName()`或`ClassLoader.getSystemClassLoader().loadClass()`尝试动态加载第三方JAR中的类时。 Java虚拟机(JVM)的类加载机制是导致此问题的关键。自JDK 1.2以来,JVM采用委托...

Global site tag (gtag.js) - Google Analytics