类的加载三种方式:
1、命令行启动应用时由JVM初始化加载
2、通过Class.forName()方法动态加载
3、通过ClassLoader.loadClass()方法动态加载
public class LoaderTest {
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader loader = HelloWorld.class.getClassLoader();
System.out.println(loader);
//使用ClassLoader.loadClass()来加载类,不会执行初始化块
//loader.loadClass("com.mytest.HelloWorld");
//使用Class.forName()来加载类,默认会执行初始化块
//Class.forName("com.mytest.HelloWorld");
//使用Class.forName()来加载类,并指定ClassLoader,初始化时不执行静态块
Class.forName("com.mytest.HelloWorld",false,loader);
}
}
Class.forName()和ClassLoader.loaderClass()区别
Class.forName():将类的.class文件加载到JVM中之外,还会对类进行解释,执行类中的static块;
ClassLoader.loaderClass():只干一件事情,就是将.class文件加载到JVM中,不会执行static中的内容,只有在newInstance才会去执行static块。
注:Class.forName(name,initialize,loader)带参函数也可控制是否加载static块,并且只有调用了newInstance()方法采用调用构造函数,创建类的对象。
自定义加载类:
package com.mytest;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class MyClassLoader extends ClassLoader{
private String root;
protected Class<?> findClass(String name) throws ClassNotFoundException{
byte[] classData = loadClassData(name);
if(null == classData){
throw new ClassNotFoundException();
}else{
return defineClass(name, classData, 0, classData.length);
}
}
private byte[] loadClassData(String className) {
String fileName = root + File.separatorChar + className.replace('.', File.separatorChar) + ".class";
try {
InputStream inputStream = new FileInputStream(fileName);
ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream();
int buffersize = 1024;
byte[] buffer = new byte[buffersize];
int length = 0;
while((length = inputStream.read(buffer)) != 1){
baOutputStream.write(buffer, 0, length);
}
return baOutputStream.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String getRoot(){
return root;
}
public void setRoot(String root){
this.root = root;
}
public static void main(String[] args) {
MyClassLoader classLoader = new MyClassLoader();
classLoader.setRoot("F:\\temp");
Class<?> eClass = null;
try {
eClass = classLoader.loadClass("com.mytest.HelloWorld");
Object object = eClass.newInstance();
System.out.println(object.getClass().getClassLoader());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}