2 回答
TA贡献1805条经验 获得超9个赞
AClassLoader
只负责定位和读取类文件,并可选择将 aProtectionDomain
与代码位置相关联,以支持安全措施。
然后它将字节传递给defineClass
每个类加载器继承的方法之一。这些方法将类文件字节作为数组或ByteBuffer
,并执行整个魔术,最终返回一个Class
对象。
这些Class
对象大多像普通对象,但你从来没有通过new
; 只有 JVM 会创建实例。此外,JVM 可以将附加信息与这些对象相关联,这些信息对于查看 Java 对象的应用程序程序员是不可见的。
内发生的事情defineClass
是特定于实现的。但它是典型的,不按原样存储类文件字节。它们可能包含执行不需要的信息,并且所需的信息可能不是当前平台的最佳格式(如字节顺序和首选数据对齐)。此外,将不同类别的相同常量折叠到一个存储中是有意义的。由于无论如何都必须检查类数据的有效性,因此将该处理步骤与将数据转换为更适合后续处理的内部格式相结合是有意义的。
关于类的完整运行时信息仍然分布在堆(如Class
实例及其关联的反射对象)和方法区(如代码、链接信息、JVM 内部结构等)上。请注意,这些名称由规范给出,即 Java 堆定义为包含所有 Java 对象的内存区域,方法区定义为元数据的存储。由于这种区别是由定义给出的,无论它是否对特定实现产生影响(毕竟,它只是 RAM),您不会在此分类中看到依赖于实现的更改。
TA贡献2065条经验 获得超13个赞
有关其工作原理的完整说明,您需要阅读 Java 虚拟机规范的第 5 章。介绍说,
" Java 虚拟机动态加载、链接和初始化类和接口。加载是查找具有特定名称的类或接口类型的二进制表示并从该二进制表示创建类或接口的过程。链接是获取一个类或接口并将其组合到 Java 虚拟机的运行时状态中,以便它可以被执行。类或接口的初始化包括执行类或接口的初始化方法”
回答具体问题:
类文件不是按原样加载到方法区中,而是作为类的特定实现(意味着 JVMS 不强制要求)内部表示加载。类(数组类除外)由类加载器加载。类加载器为给定的类创建一个类对象(即元数据)的实例。该对象在堆中的空间分配由 JVM 处理。
不。类加载器负责创建 Class 对象,因此不使用该对象的方法。
是的,Class 对象与任何其他 Java 对象的形式相同。Class 类继承自 Object,您可以像调用其他对象一样调用 equals、hachCode 等方法。
添加回答
举报