常见的三种类加载方式如下:
TransactionMain transactionMain = new TransactionMain();
Class<?> aClass = Class.forName(TransactionMain.class.getName());
ClassLoader.getSystemClassLoader().loadClass(TransactionMain.class.getName());那么下面抛出问题: 这三种加载方式有什么不同?
要回答上面这个问题,我们先来看看一个java.class文件从磁盘被加载到内存要经历那些步骤吧。

还有一点: 前两种方式都是静态加载,而最后一种方式是动态加载
从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。但是使用Class对象的newInstance()方法的时候,就必须保证:1.这个类已经加载;2.这个类已经连接了。
new关键字和newInstance()方法的区别:
newInstance:弱类型,低效率,只能调用无参构造;
new:强类型,相对高效,能调用任何Public构造。Class的装载包括3个步骤:加载(loading),连接(link),初始化(initialize)。上面也已经讲过一遍了。
Class.forName(className)实际上是调用Class.forName(className, true, this.getClass().getClassLoader())。
第二个参数,是指Class被loading后是不是必须被初始化。ClassLoader.loadClass(className)实际上调用的是ClassLoader.loadClass(name, false)。
第二个参数指Class是否被linkClass.forName(className)装载的class已经被初始化,而ClassLoader.loadClass(className)装载的class还没有被link。
一般情况下,这两个方法效果一样,都能装载Class。但如果程序依赖于Class是否被初始化,就必须用Class.forName(name)了。
例如,在JDBC编程中,常看到这样的用法:
Class.forName(“com.mysql.jdbc.Driver”)如果换成了下面这样就不行了
getClass().getClassLoader().loadClass(“com.mysql.jdbc.Driver”)因为Driver的静态代码块中需要在初始化的时候被执行,这样才可以向DriverManager去注册自己
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}