Java任意类加载方法

准备要加载的测试类test.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class test {

// 静态变量
public static int staticVar;

// 实例变量
public int instanceVar;

// 静态代码块
static
{
System.out.println("静态代码块");
}

// 构造代码块
{
System.out.println("构造代码块");
}

// 无参构造器
public test() {
System.out.println("无参构造器");
}

// 有参构造器
public test(int instanceVar){
System.out.println("有参构造器");
}

// 静态方法
public static void staticAction(){
System.out.println("静态方法");
}
}

编译为test.class文件

1
javac -encoding UTF-8 test.java -d E:\tmp

image-20260113144720966

方法一:使用URLClassLoader类

URLClassLoaderDemo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package ThreeClassLoader;

import java.net.URL;
import java.net.URLClassLoader;

public class URLClassLoaderDemo {
public static void main(String[] args) throws Exception{
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file:///E:/tmp/")});
Class<?> c = urlClassLoader.loadClass("test");
c.newInstance();
}
}

image-20260113144829780

也可以使用http://远程加载

可以在kali开个PHP服务,将编译好的文件放到目录下

1
php -S 0:80

image-20260113145708914

利用http://进行加载

1
2
3
4
5
6
7
8
9
10
11
12
13
package ThreeClassLoader;

import java.net.URL;
import java.net.URLClassLoader;

public class URLClassLoaderDemo {
public static void main(String[] args) throws Exception{
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("http://192.168.41.132/")});
Class<?> c = urlClassLoader.loadClass("test");
c.newInstance();
}
}

image-20260113145843600

方法二:使用ClassLoader.defineClass()方法

ClassLoaderDefineClassDemo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package ThreeClassLoader;

import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Paths;

public class ClassLoaderDefineClassDemo {
public static void main(String[] args) throws Exception{
ClassLoader c = ClassLoader.getSystemClassLoader();
Method cname = ClassLoader.class.getDeclaredMethod("defineClass",String.class,byte[].class,int.class,int.class);
cname.setAccessible(true);
byte[] classBytes = Files.readAllBytes(Paths.get("E:/tmp/test.class"));
Class<?> cc = (Class<?>) cname.invoke(c,"test",classBytes,0,classBytes.length);
cc.newInstance();
}
}

image-20260113151319088

方法三:使用Unsafe.defineClass()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package ThreeClassLoader;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;

public class UnsafeDefineClassDemo {
public static void main(String[] args) throws Exception{
ClassLoader cl = ClassLoader.getSystemClassLoader();
Class c = cl.getClass();
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
byte[] classBytes = Files.readAllBytes(Paths.get("E:/tmp/test.class"));
Class<?> u = unsafe.defineClass("test",classBytes,0,classBytes.length,cl,null);
u.newInstance();
}
}

image-20260113152014512


Java任意类加载方法
https://yschen20.github.io/2026/01/13/Java任意类加载的三种方法/
作者
Suzen
发布于
2026年1月13日
更新于
2026年1月13日
许可协议