《深入Java虚拟机》第二版(很老的那本,Bill Venners写的,有中文翻译那本)第八章讲解类加载器用了个
Cindy、Mom、Grandma的例子。但那个例子是错的。
发了邮件到jdk6-dev邮件列表,等待答复。顺便发这边大家讨论。
那个例子说,Cindy的parent是Mom,Mom的parent是Grandma,Grandma的parent是null也就是bootstrap class loader。
Cindy尝试加载java.io.FileReader会委派给Mom,Mom委派给Grandma,Grandma委派给bootstrap,bootstrap成功加载并一层层把Class返回出来。
这个过程完成后,书上说Cindy、Mom、Grandma都应该是initiating loader。但事实却不是如此。
代码例子:
import java.io.*;
import java.net.*;
public class TestInitiatingLoader {
public static void main(String[] args) throws Exception {
Grandma grandma = new Grandma();
Mom mom = new Mom(grandma);
Cindy cindy = new Cindy(mom);
cindy.loadClass("Dummy").newInstance(); // force class init
final String reader = "java.io.FileReader";
printStats(grandma, reader); // false
printStats(mom, reader); // false
printStats(cindy, reader); // true
}
private static void printStats(LoadedClassQueryable loader, String name) {
System.out.printf("Is %s an initiating loader of %s: %b\n",
loader.getClass().getName(),
name,
loader.foundLoadedClass(name));
}
}
interface LoadedClassQueryable {
boolean foundLoadedClass(String name);
}
class Cindy
extends URLClassLoader
implements LoadedClassQueryable {
public Cindy(ClassLoader parent) {
super(makeArgs(), parent);
}
private static URL[] makeArgs() {
try {
return new URL[] { new File(".").toURI().toURL() };
} catch (Exception e) {
e.printStackTrace();
return new URL[] { };
}
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if ("Dummy".equals(name)) {
// force Cindy to load this Dummy class
return findClass("Dummy");
}
return super.loadClass(name);
}
@Override
public boolean foundLoadedClass(String name) {
return findLoadedClass(name) != null;
}
}
class Mom
extends ClassLoader
implements LoadedClassQueryable {
public Mom(ClassLoader parent) {
super(parent);
}
@Override
public boolean foundLoadedClass(String name) {
return findLoadedClass(name) != null;
}
}
class Grandma
extends ClassLoader
implements LoadedClassQueryable {
public Grandma() {
super(null); // use bootstrap class loader as parent
}
@Override
public boolean foundLoadedClass(String name) {
return findLoadedClass(name) != null;
}
}
Dummy.java
import java.io.*;
public class Dummy {
static {
// Dummy should be loaded by Cindy.
// So Cindy will be recorded as an initiating loader for java.io.FileReader
try {
new FileReader("Dummy.class").close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果:
Is Grandma an initiating loader of java.io.FileReader: false
Is Mom an initiating loader of java.io.FileReader: false
Is Cindy an initiating loader of java.io.FileReader: true
ClassLoader.findLoadedClass()可用于确认一个类与initiating loader关系。
引用
findLoadedClass
protected final Class<?> findLoadedClass(String name)
Returns the class with the given binary name if this loader has been recorded by the Java virtual machine as an initiating loader of a class with that binary name. Otherwise null is returned.
Parameters:
name - The binary name of the class
Returns:
The Class object, or null if the class has not been loaded
Since:
1.1
读书要谨慎,切记不要人云亦云。
分享到:
相关推荐
这样,每次提交时Git都能记录是谁做出的更改。接着,你可以使用`git add`命令将新文件或更改添加到暂存区,然后使用`git commit`来保存这些更改,附带一条描述更改的提交消息。 在你对本地仓库满意后,如果要与他人...
School psychologists as researchers: An approach for initiating training and practice PsyrholoRj in thr Schoo/s Volume 21 . A d , /984 SCHOOL PSYCHOLOGISTS AS RESEARCHERS: AN APPROACH FOR ...
BLE帧结构可以分为四种类型:Advertising Channel PDU、Scanning PDUs、Initiating PDUs和Connection-oriented PDUs。 Advertising Channel PDU是BLE设备用于广播的帧结构,包括ADV_IND、ADV_DIRECT_IND、ADV_...
项目管理的过程组是一个循环的过程,包括 Initiating、 Planning、 Executing、 Monitoring and Controling、 Closing 等五个阶段。 1. Initiating:项目启动阶段,确定项目的目标、范围和deliverables。 2. ...
1. **启动过程组** (Initiating Process Group, IPG) - **4.1 制定项目章程** (Develop Project Charter, DPC): 输入包括项目启动文档、商业论证、协议等,输出是项目章程。 2. **规划过程组** (Planning Process ...
SCT Instant服务涉及多种参与者,包括发起人(Initiating Party)、收款人(Paying Party)、发起行(Initiating Bank)、收款行(Paying Bank)、中间行(Terminating or Intermediary Banks)和清算机构(Clearing and ...
整句话的翻译为:"The term 'initiative' refers to the innovative spirit, specifically the spirit of initiating proposals, plans and inventions and implementing them. The grassroots initiative is the ...
BLE协议栈的工作流程涉及五种状态:standby、advertising、scanning、initiating和connected。广告(advertising)阶段,设备可以无连接地发送数据;扫描(scanning)阶段,设备监听广播数据;发起连接(initiating...
《New Handoff Initiating Algorithm》 DSP编程指南 在信息技术领域,数字信号处理(DSP)扮演着至关重要的角色,尤其在通信系统中。本资源“NewHO.rar”包含了一本PDF格式的DSP编程专著,专注于一种名为“New Hand...
- **3.3.1 Initiating Data In Burst**: 开始输入数据的突发传输。 - **3.3.2 Sustained Data In Burst**: 维持输入数据的突发传输。 - **3.3.3 Host Pausing Data In Burst**: 主机暂停输入数据的突发传输。 - ...
Initiating PDU用于连接发起协议。 * CONNECT_REQ:连接请求帧,发起方发送该帧,广播方接收该帧。 + TxAdd:确认InitA地址为公共地址还是随机地址 + RxAdd:确认AdvA地址为公共地址还是随机地址 + LLData:数据...
整个考试指导分为五个主要的绩效领域(Performance Domains),分别是:启动(Initiating)、规划(Planning)、执行(Executing)、监控和控制(Monitoring and Controlling)、以及收尾(Closing)。此外,还包括...
项目管理框架由多个阶段构成,首先是项目启动(Project Initiating),这一阶段需要识别项目机会,定义项目范围,并获得必要的批准。接下来是项目规划(Project Planning),包括详细定义项目的工作范围、时间表、...
- **启动阶段(Initiating)**:如项目章程,明确了项目的目标、范围、主要干系人和初步的资源分配。 - **规划阶段(Planning)**:涉及范围定义、时间管理、成本估算、质量计划等,可能的交付物包括项目计划、...
引入CMMI时,可以参考IDEAL模型(Initiating、Diagnosing、Establishing、Acting、Learning)进行流程改进。IDEAL模型提供了一种结构化的改进路径,包括分析和验证问题、制定解决方案、实施解决方案、细化和优化解决...
此外,项目管理还包括启动和规划过程,如启动会议(initiating meeting)和启动会(kick-off meeting)的组织,项目章程和项目管理计划的制定。项目章程包含项目的基本信息和目标,是项目启动过程组的重要输出。项目...
1. 项目启动会(Initiating Meeting) 项目启动会是项目生命周期的起点,通常在启动阶段结束后召开。主要任务是发布项目章程,正式任命项目经理,并赋予其调动组织资源的权力。会议前需识别干系人,形成干系人登记...