Java:如何将存储为byte []的类加载到JVM中?

siv*_*udh 23 java classloader

如果已将整个.class文件序列化为byte [],并假设类的名称已知(与byte []一起传递),如何转换byte [] - > Class - >然后将其加载到JVM以便我以后可以通过调用Class.forName()来使用它?

注意: 我这样做是因为我将.class发送到另一台主机,并且主机的JVM不知道这个.class.

Ale*_*ler 26

我实际上正在使用这样的东西在测试中将一组类定义作为byte []提供给ClassLoader:

  public static class ByteClassLoader extends URLClassLoader {
    private final Map<String, byte[]> extraClassDefs;

    public ByteClassLoader(URL[] urls, ClassLoader parent, Map<String, byte[]> extraClassDefs) {
      super(urls, parent);
      this.extraClassDefs = new HashMap<String, byte[]>(extraClassDefs);
    }

    @Override
    protected Class<?> findClass(final String name) throws ClassNotFoundException {
      byte[] classBytes = this.extraClassDefs.remove(name);
      if (classBytes != null) {
        return defineClass(name, classBytes, 0, classBytes.length); 
      }
      return super.findClass(name);
    }

  }
Run Code Online (Sandbox Code Playgroud)

  • @ ShaChris23 - 当然,为什么不呢?@Stephen C - 这似乎是Java类加载器可以做的有限视图.为什么你说可能不是? (3认同)

Mat*_*att 9

使用的defineClass(字符串,字节[],INT,INT)从方法类加载器


Jé *_*eue 7

扩展ClassLoader然后实现必要的调用以获取您的byte[]内部方法defineClass()。相反,您可以在findClass(). 因此,您将在开始时加载此 ClassLoader,或者在需要通过数组定义类时使用它。

public class ByteArrayClassLoader extends ClassLoader {

    public Class findClass(String name) {
        byte[] ba = /* go obtain your byte array by the name */;

        return defineClass(name,ba,0,ba.length);
    }

}
Run Code Online (Sandbox Code Playgroud)