java - jvm什么时候加载instanceof操作符的导入类?
问题描述
假设我有两个班级 A 和 B。
class A{}
import A;
class B{}
那么如果在某个对象上我在main
方法中做if(object instanceof B)
,它会加载类A
以及它在类的导入语句中B
吗?类加载器究竟何时会在运行时加载这些类?
解决方案
有两点需要注意:
import
语句不会影响类的运行时行为。不会为 import 语句生成任何代码。而如果你只是在B类中导入A类,那么加载B类不会导致A类被加载。类加载时间和类初始化时间不同。
类的生命周期是在使用之前加载、链接和初始化(参见JLS 第 12 章)。
加载由类加载器执行,包括定位类文件、将其读入 a
byte[]
并调用ClassLoader::defineClass
.链接由 JVM 核心代码执行,包括符号引用的验证、准备和解析。JLS 12.3是这样说的:
该规范允许在何时发生链接活动(以及由于递归,加载)时实现灵活性,前提是尊重 Java 编程语言的语义,在初始化之前对类或接口进行完全验证和准备,并且在链接期间检测到的错误会在程序中的某个点被抛出,在该点上,程序采取了一些可能需要链接到错误中涉及的类或接口的操作。
这意味着我们无法具体说明何时执行不同的任务。
在链接所有相关类之后进行初始化。根据JLS 12.4.1:
类或接口类型 T 将在以下任何一项第一次出现之前立即初始化:
- T 是一个类,并创建了一个 T 的实例。
- 调用由 T 声明的静态方法。
- 分配了一个由 T 声明的静态字段。
- 使用了由 T 声明的静态字段,并且该字段不是常量变量(第 4.12.4 节)。
根据 JLS(见上文),我们无法准确说明何时B
加载和链接。我们只能说它发生在B
初始化之前......如果它被初始化。(您可以通过打开一些 JVM 日志来了解类加载的顺序。但是,顺序可能会因 JVM 供应商和版本而异。)
根据 JLS(见上文),当您的方法创建B
第一个实例时(通常)会发生初始化。假设在您的 Question 中已经初始化为一个实例,则初始化将在测试之前发生。如果不是,则不会被测试初始化。B
main
object
B
instanceof
B
instanceof
从表面上看,不需要A
加载类。(这取决于 class 是否以及如何B
实际使用 class A
,以及代码库的其他部分是否/如何使用A
。)
推荐阅读
- node.js - 在控制台中设置 Elastic Beanstalk 环境变量与从部署中传递它们
- python - 在 C++ 中为具有不同维度的数组实现 numpy.tensordot 代码
- typescript - 如何使用 chai 断言将数组元素的字符串与预期值进行比较
- python - 无法使用 python、selenium 和美丽的汤来抓取评论页面
- javascript - 如何在原生相机上绘制网页元素?
- python - 如何使用 webbrowser Edge 在 Selenium 中处理“打开此文件”?
- reactjs - ReactDOM 不呈现简单的 h1 元素
- memory - WebLogic 托管服务器在应用程序部署后开始花费更多时间
- odoo - 我如何将父值传递给 one 2 many 并在 odoo 12 中的 if 中使用
- python - c# 和 python 不再能够找到文件