使用forName动态加载类文件

简介:

动态加载(Dynamic Loading)是指在程序运行时加载需要的类库文件,对Java程序来说,一般情况下,一个类文件在启动时或首次初始化时会被加载到内存中,而反射则可以在运行时再决定是否需要加载一个类,比如从Web上接受一个String参数作为类名,然后在JVM中加载并初始化,这就是动态加载,此动态加载通常是通过Class.forName(String)实现的,只是这个forName()方法到底是什么意思?

我们知道一个类文件只有在被加载到内存中后才可能生成实例对象,也就是说一个对象的生成必然会经过以下两个步骤:

1.加载到内存中生成Class的实例对象.

2.通过new关键字生成实例对象.

如果我们使用的是import关键字产生的依赖包,JVM在启动时会自动加载所有依赖包下的类文件,这没有什么问题,如果要动态加载一个类文件呢?就需要使用forName方法了.

为什么要使用forName()方法动态加载一个类文件呢?那是因为我们不知道生成的实例对象是什么类型(如果知道就不用动态加载).而且方法和属性都不可访问.

动态加载的意义是什么?

意义在于:加载一个类,即表示要初始化该类的static变量,特别是static代码块,在这里我们可以做大量的工作,比如注册自己,初始化环境等,这才是要重点关注的逻辑.

例如下代码:

复制代码
 1 public class Client {
 2     public static void main(String[] args) throws Exception{
 3         //动态加载
 4         Class.forName("cn.summerchill.test.Utils");        
 5     }
 6 }
 7 
 8 class Utils{
 9     //静态代码块
10     static{
11         System.out.println("Do Something");
12     }
13     //静态方法
14     public static void doStuff(){}
15 }
复制代码

 

在Client类中,我们并没有对Utils做任何初始化,只是通过forName方法加载了Utils类,但是却能产生了一个"Do Something"的输出,这就是Utils类被加载之后,JVM会自动初始化其static变量和static代码块,这就是类加载机制所决定的.

对于此种动态加载,最经典的就是数据库驱动程序中的加载片段.代码如下:

复制代码
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/db?user=admin&password=admin";
Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
..........................
复制代码

在没有Hibernate和Ibatis,MyBatis等ORM框架的情况下,基本上每个系统都会有这么一个JDBC的连接类,然后提供诸如Query,Delete等的方法.

加上Class.forName("com.mysql.jdbc.Driver")没有任何的输出却非常的有用.

复制代码
 1 public class Driver extends NonRegisteringDriver implements java.sql.Driver {
 2     static {
 3         try {
 4             java.sql.DriverManager.registerDriver(new Driver());
 5         } catch (SQLException E) {
 6             throw new RuntimeException("Can't register driver!");
 7         }
 8     }
 9 
10     public Driver() throws SQLException {
11     }
12 }
复制代码

 

该程序的逻辑是:数据库的驱动程序已经由NonRegisteringDriver实现了,Driver类只是负责把自己注册到DriverManager中.

当程序动态加载驱动时,也就是执行到Class.forName("****")时,Driver类会被加载到内存中,于是static代码块开始执行,也就是把自己注册到DriverManager中.

需要说明的是,forName只是把一个类加载到内存中,并不保证由此产生一个实例对象,也不会执行任何方法,之所以会初始化static代码,那是由类加载机制所决定的.

而不是由forName决定的,也就是说,如果没有static属性或者static代码块,forName就只是加载类,没有任何执行行为.

forName只是加载类,并不执行任何代码.

 


本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/5626166.html,如需转载请自行联系原作者

相关文章
|
1月前
|
前端开发 Java API
类加载器“如果我定义了一个类名与Java核心类类名相同,那它还能被加载吗?”
类加载器“如果我定义了一个类名与Java核心类类名相同,那它还能被加载吗?”
|
2月前
|
存储 Java 编译器
深入理解JVM - 类文件结构
深入理解JVM - 类文件结构
58 1
|
7月前
|
Java 数据安全/隐私保护
Java自定义类加载器的编写步骤
Java自定义类加载器的编写步骤
42 0
|
存储 XML 安全
JVM系列5-类文件结构
JVM系列5-类文件结构
46 0
|
存储 Java 虚拟化
JVM加载class文件的原理机制是什么?
JVM加载class文件的原理机制是什么?
|
安全 前端开发 Java
ClassLoader 加载| 学习笔记
快速学习 ClassLoader 加载
ClassLoader 加载| 学习笔记
|
安全 前端开发 Java
ClassLoader加载|学习笔记
快速学习ClassLoader加载
ClassLoader加载|学习笔记
|
Java
打印当前ClassLoader 加载了哪些Jar
打印当前ClassLoader 加载了哪些Jar
186 1
|
JavaScript Java Android开发
dex加载后导入类报错
牙叔教程 简单易懂
265 0
|
Java 数据库连接 API
DAY6:你必须知道的java虚拟机之类篇——类文件的加载(2)
1.类加载的七个过程清楚吗? 2.和类初始化相关的6个条件能说一下吗 3.数组的加载和引用类型的加载有哪些区别 这几个知识点还说不上来的,传送门