如何获取数组类的类定义byte []?

时间:2012-09-06 23:13:40

标签: java classloader

我试图了解Java类加载器的工作原理,特别是defineClass(String,byte[],int,int)方法。假设我想加载NonIntrinsicType的类定义。我知道我可以找到NonIntrinsicType的* .class文件,将其内容序列化为名为byte[]的{​​{1}},然后调用bytes

我难以理解的奇怪情况是,如何获得defineClass(null,bytes,0,bytes.length)byte[]的类定义 - 换句话说,如果我的应用程序请求类的定义[LNonIntrinsicType的实例,我没有与此类类型对应的* .class文件。如何获得此类型定义的NonIntrinsicType[]

你可能想知道我为什么要这样做。我基本上试图创建一个网络类加载器,它的“本地”JVM在其类路径上有类定义,而“远程”JVM在其类路径上没有上述类定义。 “Remote”遇到byte[]的实例,并从“Local”请求该类类型的定义,但我的“Local”JVM找不到NonIntrinsicType[]的类文件,因此无法将类定义NonIntrinsicType[]提供给“远程”。

已添加9/7/2010

我应该提到的一件事......我正在使用byte[]Socket来接收“本地”发送到“远程”的消息。我在“远程”一侧创建了ObjectInputStream的自定义扩展程序,并覆盖了ObjectInputStream。当传入消息包含尚未加载的类的实例时,这是我的“远程”JVM获得的第一个通知。我有另一个套接字用于传递类定义,所以当第一个套接字接收到一个尚未加载的类的实例时,它通过第二个套接字从“本地”JVM请求该类的定义。

当我的自定义protected Class<?> resolveClass(ObjectStreamClass)传递ObjectInputStream.resolveClass(ObjectStreamClass)并返回数组类型的类名(名称看起来像ObjectStreamClass)时,会出现问题。我可以轻松地解析基类级别[Lsome.ClassName;并首先加载它 - 这是在调用some.ClassName时完成的,我在这里获得基类级别的NetworkClassLoader.getInstance.loadClass()然后用它在该方法调用中调用byte[]

我现在明白你可能无法获得数组类型的类定义的defineClass(),因此这让我试图弄清楚如何找到数组类型的byte[]实例并返回它。以下是我在“远程”JVM的邮件接收Class<?>上的自定义resolveClassObjectInputStream方法的代码:

Socket

5 个答案:

答案 0 :(得分:3)

您不需要为[LType创建定义。如果您有Class,则可以使用反射创建该类的array

Object array = Array.newInstance(yourClass, dimensions);

答案 1 :(得分:2)

您无法控制数组的加载,因为它们未加载。没有什么可加载的。数组没有类。没有课程定义。没有字节[]。

答案 2 :(得分:0)

唯一可行的方法是修补JVM的defineClass(...)方法以查找所需的类,然后将它们存储起来供以后使用。

答案 3 :(得分:0)

数组类由JVM创建,无需调用defineClass()

请参阅http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.3.3

答案 4 :(得分:0)

摘自ClassLoader javadoc:

  

数组类的类对象不是由类加载器创建的,而是   是根据Java运行时的需要自动创建的。班级   数组类的加载器,由Class.getClassLoader()返回   与元素类型的类加载器相同;如果元素类型   是一个原始类型,然后数组类没有类加载器。

理解你的类加载器如何被要求为[LNonIntrinsicType创建一个类会很有趣。感觉就像你在做一些自定义的事情。如果您能够更详细地描述您正在做什么,我们可以更好地了解您的问题。当要求您的类加载器定义[LNonIntrinsicType时,调用堆栈是什么?