`
ravenex
  • 浏览: 11268 次
  • 性别: Icon_minigender_1
  • 来自: 体育仓库
社区版块
存档分类
最新评论

谁是initiating loader

阅读更多
《深入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


读书要谨慎,切记不要人云亦云。
分享到:
评论
2 楼 ravenex 2012-11-05  
chong_zh 写道
例子中的Cindy,Mom,Grandma并没有载入委派关系,委派是指调用被委派对象的loadClass方法,以Cindy的loadClass方法为例:

  public Class<?> loadClass(String name) throws ClassNotFoundException {  
    if ("Dummy".equals(name)) {  
      // force Cindy to load this Dummy class  
      return findClass("Dummy");  
    }  
    return getParent().loadClass(name);  
  } 


所以您没看懂super.loadClass(name)的意义。这里调用的是ClassLoader.loadClass(String name)(因为URLClassLoader没有override掉ClassLoader的loadClass方法),里面一进去如果检查到指定名字的类没加载过就会用parent.loadClass(name),或如果parent是null则用bootstrap class loader来加载。
1 楼 chong_zh 2012-08-26  
例子中的Cindy,Mom,Grandma并没有载入委派关系,委派是指调用被委派对象的loadClass方法,以Cindy的loadClass方法为例:

  public Class<?> loadClass(String name) throws ClassNotFoundException {  
    if ("Dummy".equals(name)) {  
      // force Cindy to load this Dummy class  
      return findClass("Dummy");  
    }  
    return getParent().loadClass(name);  
  } 

相关推荐

    initiating_git

    这样,每次提交时Git都能记录是谁做出的更改。接着,你可以使用`git add`命令将新文件或更改添加到暂存区,然后使用`git commit`来保存这些更改,附带一条描述更改的提交消息。 在你对本地仓库满意后,如果要与他人...

    School psychologists as researchers: An approach for initiating training and practice

    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)学习记录文本.docx

    BLE帧结构可以分为四种类型:Advertising Channel PDU、Scanning PDUs、Initiating PDUs和Connection-oriented PDUs。 Advertising Channel PDU是BLE设备用于广播的帧结构,包括ADV_IND、ADV_DIRECT_IND、ADV_...

    IT项目管理案例分析大全.doc

    项目管理的过程组是一个循环的过程,包括 Initiating、 Planning、 Executing、 Monitoring and Controling、 Closing 等五个阶段。 1. Initiating:项目启动阶段,确定项目的目标、范围和deliverables。 2. ...

    pmp47个过程组和各个过程的输入输出及常用缩写.docx

    1. **启动过程组** (Initiating Process Group, IPG) - **4.1 制定项目章程** (Develop Project Charter, DPC): 输入包括项目启动文档、商业论证、协议等,输出是项目章程。 2. **规划过程组** (Planning Process ...

    欧盟SEPA中即时支付SCT Instant原理介绍文档

    SCT Instant服务涉及多种参与者,包括发起人(Initiating Party)、收款人(Paying Party)、发起行(Initiating Bank)、收款行(Paying Bank)、中间行(Terminating or Intermediary Banks)和清算机构(Clearing and ...

    英语四级考试翻译模拟练习题:层首创精神.docx

    整句话的翻译为:"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 ...

    CC254xBLE软件开发指南.pdf

    BLE协议栈的工作流程涉及五种状态:standby、advertising、scanning、initiating和connected。广告(advertising)阶段,设备可以无连接地发送数据;扫描(scanning)阶段,设备监听广播数据;发起连接(initiating...

    NewHO.rar_DSP编程_PDF_

    《New Handoff Initiating Algorithm》 DSP编程指南 在信息技术领域,数字信号处理(DSP)扮演着至关重要的角色,尤其在通信系统中。本资源“NewHO.rar”包含了一本PDF格式的DSP编程专著,专注于一种名为“New Hand...

    ATA present

    - **3.3.1 Initiating Data In Burst**: 开始输入数据的突发传输。 - **3.3.2 Sustained Data In Burst**: 维持输入数据的突发传输。 - **3.3.3 Host Pausing Data In Burst**: 主机暂停输入数据的突发传输。 - ...

    低功耗蓝牙BLE学习记录.doc

    Initiating PDU用于连接发起协议。 * CONNECT_REQ:连接请求帧,发起方发送该帧,广播方接收该帧。 + TxAdd:确认InitA地址为公共地址还是随机地址 + RxAdd:确认AdvA地址为公共地址还是随机地址 + LLData:数据...

    project management professional exam outline

    整个考试指导分为五个主要的绩效领域(Performance Domains),分别是:启动(Initiating)、规划(Planning)、执行(Executing)、监控和控制(Monitoring and Controlling)、以及收尾(Closing)。此外,还包括...

    项目管理学习总结PPT.pptx

    项目管理框架由多个阶段构成,首先是项目启动(Project Initiating),这一阶段需要识别项目机会,定义项目范围,并获得必要的批准。接下来是项目规划(Project Planning),包括详细定义项目的工作范围、时间表、...

    PMP可交付成果

    - **启动阶段(Initiating)**:如项目章程,明确了项目的目标、范围、主要干系人和初步的资源分配。 - **规划阶段(Planning)**:涉及范围定义、时间管理、成本估算、质量计划等,可能的交付物包括项目计划、...

    CMMI Appraisal

    引入CMMI时,可以参考IDEAL模型(Initiating、Diagnosing、Establishing、Acting、Learning)进行流程改进。IDEAL模型提供了一种结构化的改进路径,包括分析和验证问题、制定解决方案、实施解决方案、细化和优化解决...

    项目管理过程ITTO汇总(含书签).pdf

    此外,项目管理还包括启动和规划过程,如启动会议(initiating meeting)和启动会(kick-off meeting)的组织,项目章程和项目管理计划的制定。项目章程包含项目的基本信息和目标,是项目启动过程组的重要输出。项目...

    PMP八大会议

    1. 项目启动会(Initiating Meeting) 项目启动会是项目生命周期的起点,通常在启动阶段结束后召开。主要任务是发布项目章程,正式任命项目经理,并赋予其调动组织资源的权力。会议前需识别干系人,形成干系人登记...

Global site tag (gtag.js) - Google Analytics