繁体   English   中英

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

[英]Java: How to load Class stored as byte[] into the JVM?

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

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

我实际上正在使用这样的东西在测试中将一组类定义作为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);
    }

  }

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

扩展ClassLoader ,然后实现必要的调用,以获取方法defineClass() byte[] 相反,你可以在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);
    }

}

好的,所以这就是我的所作所为:

public class AgentClassLoader extends ClassLoader
{
  public void loadThisClass(ClassByte classByte_)
  {
    resolveClass(defineClass(classByte_.getName(),
                             classByte_.getBytes(),
                             0,
                             classByte_.getBytes().length));
  }
}

我希望将类加载到JVM中? 如果这确实有效,为什么Java实现器不同时生成defineClass和resolveClass公共方法? 我真的很想知道他们在想什么。 谁能开导我?

为了完整起见,这里是ClassByte

import java.io.Serializable;

public class ClassByte implements Serializable
{
  private String name;
  private byte[] bytes;

  ClassByte(String name_, byte[] bytes_)
  {
    name  = name_;
    bytes = bytes_;
  }

  public String getName()
  {
    return name;
  }

  public byte[] getBytes()
  {
    return bytes;
  }
}

Alex的答案是正确的,但如果你有类之间的继承关系,你需要确保首先加载父类。 否则,类加载器将无法定义它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM