假设我有两个班级A和B。
class A{}
import A;
class B{}
Run Code Online (Sandbox Code Playgroud)
然后,如果我在main方法中对某个对象进行操作if(object instanceof B),它将加载类A以及在类的import语句中是否存在该类B?classloader何时确切在运行时加载这些类?
有两件事要注意:
一条import语句不会影响类的运行时行为。不会为import语句生成任何代码。而且,如果仅将类A导入类B,则加载类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(通常)B是在您的main方法创建第一个实例时发生的。假设object您的Question中的对象已初始化为B实例,则在instanceof测试之前已经进行了初始化。如果不是,则B不会被instanceof测试初始化。
从表面上看,不需要A加载类。(这取决于类是否以及如何B实际使用类A,以及是否/如何使用代码库的其他部分A。)
| 归档时间: |
|
| 查看次数: |
69 次 |
| 最近记录: |