如果有人将整个.class文件序列化为byte [],并假设该类的名称已知(与byte []一起传递),那么如何转换byte [] - >类 - >然后将它加载到JVM,以便稍后通过调用Class.forName()?
来使用它注意: 我这样做是因为我将.class发送到另一台主机,并且主机的JVM不知道这个.class。
答案 0 :(得分: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);
}
}
答案 1 :(得分:9)
答案 2 :(得分:4)
扩展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);
}
}
答案 3 :(得分:1)
好的,这就是我的所作所为:
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;
}
}
答案 4 :(得分:0)
Alex的答案是正确的,但如果你有类之间的继承关系,你需要确保首先加载父类。否则,类加载器将无法定义它。