java中class.forName和classLoader都可用来对类进行加载。前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。而classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块(网上有很多文章说,static块在类第一次被加载是执行,是错误的,比如这个人的博客:https://yq.aliyun.com/articles/58333)。
我们可以通过一个小例子来验证一下:
class MyClass1 { static {//静态块 System.out.println("static block "); } } public class Main { Class[] classArray = { MyClass1.class//这样引用该类,必然需要将该类加载到虚拟机中 }; public static void main(String[] args){ System.out.println("hello word"); } }
执行结果:并没有输出" static bolck"
Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象 。比如:
Static Class forName(String name, boolean initialize, ClassLoader loader)
将 initialize 设定为 false,这样在加载类时并不会立即运行静态区块,而会在使用类建立对象时才运行静态区块。
其实当你调用Class.forName("classname")的时候相当于:
Class.forName("classname",true,this.getClass().getClassLoader());
什么情况下使用class.forname?
在一些应用中,无法事先知道使用者将加载什么类,而必须让使用者指定类名称以加载类,可以使用 Class 的静态 forName() 方法实现动态加载类。下面的范例让你可以指定类名称来获得类的相关信息。例如我们最熟悉的数据库驱动就是通过显示的class.forname来夹在数据库驱动类的,因为jvm启动的时候根本不知道你需要加在mysql的驱动包还是sqlserver的数据库驱动包。
/* 连接mysql 时装载的驱动类以及连接字符串 */ Class.forName(“com.mysql.jdbc.Driver”);//1 DriverManager.getConnection(“jdbc:mysql://localhost:3306/test”,”root”,”123”);//2 /* 连接SQLServer2005 时装载的驱动类以及连接字符串 */ Class.forName(“com.microsoft.sqlserver.jdbc.SQLServerDriver”); DriverManager.getConnection(“jdbc:sqlserver://localhost:1433;databaseName=pubs”,”sa”, ””);
引用:http://blog.csdn.net/u011202334/article/details/51497998
http://blog.csdn.net/berber78/article/details/46472789