ClassLoader章节我们讲了通过ClassLoader类的defineClass0/1/2方法我们可以直接向JVM中注册一个类,如果ClassLoader被限制的情况下我们还可以使用UnsafedefineClass方法来实现同样的功能。
    Unsafe提供了一个通过传入类名、类字节码的方式就可以定义类的defineClass方法:
    public native Class defineClass(String var1, byte[] var2, int var3, int var4);
    public native Class<?> defineClass(String var1, byte[] var2, int var3, int var4, ClassLoader var5, ProtectionDomain var6);
    使用Unsafe创建TestHelloWorld对象:

    1. // 使用Unsafe向JVM中注册com.anbai.sec.classloader.TestHelloWorld类
    2. Class helloWorldClass = unsafe1.defineClass(TEST_CLASS_NAME, TEST_CLASS_BYTES, 0, TEST_CLASS_BYTES.length);

    或调用需要传入类加载器和保护域的方法:

    1. // 获取系统的类加载器
    2. ClassLoader classLoader = ClassLoader.getSystemClassLoader();
    3. // 创建默认的保护域
    4. ProtectionDomain domain = new ProtectionDomain(
    5. new CodeSource(null, (Certificate[]) null), null, classLoader, null
    6. );
    7. // 使用Unsafe向JVM中注册com.anbai.sec.classloader.TestHelloWorld类
    8. Class helloWorldClass = unsafe1.defineClass(
    9. TEST_CLASS_NAME, TEST_CLASS_BYTES, 0, TEST_CLASS_BYTES.length, classLoader, domain
    10. );

    Unsafe还可以通过defineAnonymousClass方法创建内部类,这里不再多做测试。
    注意:
    这个实例仅适用于Java 8以前的版本如果在Java 8中应该使用应该调用需要传类加载器和保护域的那个方法。Java 11开始Unsafe类已经把defineClass方法移除了(defineAnonymousClass方法还在),虽然可以使用java.lang.invoke.MethodHandles.Lookup.defineClass来代替,但是MethodHandles只是间接的调用了ClassLoaderdefineClass,所以一切也就回到了ClassLoader