java类的动态加载
java动态加载的机制:
ClassLoader->SecureClassloader–>URLClassLoader–>AppClassLoader
loadClass–>findClass(重写方法)–>defineClass(从字节码加载类)
初始化的时候会加载静态代码块
实例化的时候会加载构造代码块、无参构造函数
1、URLClassLoader动态加载任意类
测试静态类
package loadClass;import java.io.IOException;public class test {static {try {Runtime.getRuntime().exec("calc");} catch (IOException e) {e.printStackTrace();}}
}
测试动态加载:
package loadClass;import com.sun.jndi.toolkit.url.UrlUtil;
import serializes.Person;import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;public class loadclass_test {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, MalformedURLException {//file协议加载//URLClassLoader urlClassLoader = new URLClassLoader(new URL[] {new URL("file:///C:\\temp\\")}); //文件所在目录//http协议加载//URLClassLoader urlClassLoader = new URLClassLoader(new URL[] {new URL("http://127.0.0.1:888/")});//jar协议URLClassLoader urlClassLoader = new URLClassLoader(new URL[] {new URL("jar:file:///C:\\temp\\test.jar!/")});Class<?> loadClass = urlClassLoader.loadClass("loadClass.test"); //全名:包名+类名loadClass.newInstance();}
}
执行完成截图:
2、defineClass 动态加载任意类
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); //获取系统的类加载器(classloader)Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);defineClass.setAccessible(true);byte[] path = Files.readAllBytes(Paths.get("C:\\temp\\test.class"));Class test = (Class)defineClass.invoke(systemClassLoader, "loadClass.test", path, 0, path.length);test.newInstance();
3、Unsave动态加载任意类:
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();Class c = Unsafe.class;Field theUnsafe = c.getDeclaredField("theUnsafe");theUnsafe.setAccessible(true);Unsafe unsafe = (Unsafe)theUnsafe.get(null);byte[] path = Files.readAllBytes(Paths.get("C:\\temp\\test.class"));Class<?> test1 = unsafe.defineClass("loadClass.test", path, 0, path.length, systemClassLoader, null);test1.newInstance();
编译方法:
javac test.java————>test.class
test.class——>test.jar
打包成jar包:jar cvf 要生成的jar文件名 类名