`

Java的类装载器(Class Loader)和命名空间(NameSpace)

    博客分类:
  • java
阅读更多

Java的类装载器(Class Loader)和命名空间(NameSpace)  

摘要

Java的类装载器是Java动态性的核心,本文将向大家简要介绍Java的类装载器,及相关的parent delegation模型,命名空间,运行时包等概念,同时讨论一些在学习中容易混淆的问题。 

类装载器的功能及分类

顾名思义,类装载器是用来把类(class)装载进JVM的。JVM规范定义了两种类型的类装载器:启动内装载器(bootstrap)和用户自定义装载器(user-defined class loader)。 

bootstrap是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。由例1可以看出,java.lang.Object是由bootstrap装载的。 

Java提供了抽象类ClassLoader,所有用户自定义类装载器都实例化自ClassLoader的子类。 System Class Loader是一个特殊的用户自定义类装载器,由JVM的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类。系统类装载器可以通过ClassLoader.getSystemClassLoader() 方法得到。

例1,测试你所使用的JVM的ClassLoader

/*LoaderSample1.java*/
public class LoaderSample1 {
    public static void main(String[] args) {
        Class c;
        ClassLoader cl;
        cl = ClassLoader.getSystemClassLoader();
        System.out.println(cl);
        while (cl != null) {
            cl = cl.getParent();
            System.out.println(cl);
        }
        try {
            c = Class.forName("java.lang.Object");
            cl = c.getClassLoader();
            System.out.println("java.lang.Object's loader is " + cl);
            c = Class.forName("LoaderSample1");
            cl = c.getClassLoader();
            System.out.println("LoaderSample1's loader is " + cl);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在我的机器上(Sun Java 1.4.2)的运行结果

sun.misc.Launcher$AppClassLoader@1a0c10f
sun.misc.Launcher$ExtClassLoader@e2eec8
null 
java.lang.Object's loader is null
LoaderSample1's loader is sun.misc.Launcher$AppClassLoader@1a0c10f

第一行表示,系统类装载器实例化自类sun.misc.Launcher$AppClassLoader 

第二行表示,系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoader 

第三行表示,系统类装载器parent的parent为bootstrap 

第四行表示,核心类java.lang.Object是由bootstrap装载的 

第五行表示,用户类LoaderSample1是由系统类装载器装载的 

parent delegation模型

从1.2版本开始,Java引入了双亲委托模型,从而更好的保证Java平台的安全。在此模型下,当一个装载器被请求装载某个类时,它首先委托自己的parent去装载,若parent能装载,则返回这个类所对应的Class对象,若parent不能装载,则由parent的请求者去装载。

如图1所示,loader2的parent为loader1,loader1的parent为system class loader。假设loader2被要求装载类MyClass,在parent delegation模型下,loader2首先请求loader1代为装载,loader1再请求系统类装载器去装载MyClass。若系统装载器能成功装载,则将MyClass所对应的Class对象的reference返回给loader1,loader1再将reference返回给loader2,从而成功将类MyClass装载进虚拟机。若系统类装载器不能装载MyClass,loader1会尝试装载MyClass,若loader1也不能成功装载,loader2会尝试装载。若所有的parent及loader2本身都不能装载,则装载失败。

若有一个能成功装载,实际装载的类装载器被称为定义类装载器,所有能成功返回Class对象的装载器(包括定义类装载器)被称为初始类装载器。如图1所示,假设loader1实际装载了MyClass,则loader1为MyClass的定义类装载器,loader2和loader1为MyClass的初始类装载器。

图 1 parent delegation模型

需要指出的是,Class Loader是对象,它的父子关系和类的父子关系没有任何关系。一对父子loader可能实例化自同一个Class,也可能不是,甚至父loader实例化自子类,子loader实例化自父类。假设MyClassLoader继承自ParentClassLoader,我们可以有如下父子loader:

ClassLoader loader1 = new MyClassLoader();
//参数 loader1 为 parent
ClassLoader loader2 = new ParentClassLoader(loader1); 

那么parent delegation模型为什么更安全了?因为在此模型下用户自定义的类装载器不可能装载应该由父亲装载器装载的可靠类,从而防止不可靠甚至恶意的代码代替由父亲装载器装载的可靠代码。实际上,类装载器的编写者可以自由选择不用把请求委托给parent,但正如上所说,会带来安全的问题。

命名空间及其作用

每个类装载器有自己的命名空间,命名空间由所有以此装载器为创始类装载器的类组成。不同命名空间的两个类是不可见的,但只要得到类所对应的Class对象的reference,还是可以访问另一命名空间的类。

例2演示了一个命名空间的类如何使用另一命名空间的类。在例子中,LoaderSample2由系统类装载器装载,LoaderSample3由自定义的装载器loader负责装载,两个类不在同一命名空间,但LoaderSample2得到了LoaderSample3所对应的Class对象的reference,所以它可以访问LoaderSampl3中公共的成员(如age)。

例2不同命名空间的类的访问

/*LoaderSample2.java*/
import java.net.*;
import java.lang.reflect.*;
public class LoaderSample2 {
    public static void main(String[] args) {
        try {
            String path = System.getProperty("user.dir");
            URL[] us = {new URL("file://" + path + "/sub/")};
            ClassLoader loader = new URLClassLoader(us);
            Class c = loader.loadClass("LoaderSample3");
            Object o = c.newInstance();
            Field f = c.getField("age");
            int age = f.getInt(o);
            System.out.println("age is " + age);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
/*sub/Loadersample3.java*/
public class LoaderSample3 {
    static {
        System.out.println("LoaderSample3 loaded");
    }
    public int age = 30;
}

编译:javac LoaderSample2.java; javac sub/LoaderSample3.java

运行:java LoaderSample2

LoaderSample3 loaded
age is 30

从运行结果中可以看出,在类LoaderSample2中可以创建处于另一命名空间的类LoaderSample3中的对象并可以访问其公共成员age。

运行时包(runtime package)

由同一类装载器定义装载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看的定义类装载器是否相同。只有属于同一运行时包的类才能互相访问包可见的类和成员。这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自己定义了一个类java.lang.Yes,并用用户自定义的类装载器装载,由于java.lang.Yes和核心类库java.lang.*由不同的装载器装载,它们属于不同的运行时包,所以java.lang.Yes不能访问核心类库java.lang中类的包可见的成员。 

总结

在简单讨论了类装载器,parent delegation模型,命名空间,运行时包后,相信大家已经对它们的作用有了一定的了解。命名空间并没有完全禁止属于不同空间的类的互相访问,双亲委托模型加强了Java的安全,运行时包增加了对包可见成员的保护。

分享到:
评论

相关推荐

    c#学习笔记.txt

    接口可以是命名空间或类的成员,并且可以包含下列成员的签名:方法属性 索引器. 一个接口可从一个或多个基接口继承。接口可由类实现。实现的接口的标识符出现在类的基列表中。被继承的接口称为该接口的显式基接口。...

    freemark学习文档

    - **`node_namespace`**:获取节点的命名空间。 - **`float`**:处理浮点数相关的操作。 - **`size`**:获取集合或数组的大小。 - **`cap_first`**:将字符串的首字母转换为大写。 - **`number`**:处理数值相关的...

    FX5UPLC以太网通讯实例:SOCKET通讯、SLMP协议通讯、JE-C伺服电机控制及Modbus通讯等真实验证程序套

    内容概要:本文详细介绍了三菱FX5U PLC在工业自动化领域的以太网通讯实战经验,涵盖多种常见通讯方式的具体实现方法。主要内容包括:两台PLC之间的Socket通讯,通过C#上位机使用SLMP协议读取PLC寄存器,JE-C伺服电机的以太网控制,以及Modbus RTU和TCP的应用。每种通讯方式均提供了具体的代码示例和调试技巧,确保读者能够快速理解和应用。此外,还特别强调了常见的避坑指南,帮助解决实际操作中可能出现的问题。 适合人群:从事工业自动化、PLC编程及相关领域的工程师和技术人员,特别是那些希望深入了解三菱FX5U PLC以太网通讯机制的人群。 使用场景及目标:适用于需要进行PLC间通讯、PLC与上位机通讯、伺服电机控制以及Modbus协议应用的实际工程项目。目标是提高通讯效率,减少调试时间和错误发生率。 其他说明:文中提供的代码均为经过产线验证的真实程序,可以直接应用于实际项目中。同时,作者分享了许多宝贵的实践经验,有助于读者更好地掌握相关技能并避免常见错误。

    2025年下半年电子商务设计师考试电子商务基础知识真题.doc

    2025年下半年电子商务设计师考试电子商务基础知识真题.doc

    中国粮食安全系统转型指数研究数据集(2000-2021)

    作者基于“自然—社会—经济”复合系统的三重视角,将粮食安全系统划分为粮食生产的资源与环境、生产与供给、分配与消费3个层面,运用“压力—状态—响应(Pressure-State-Response, PSR)”模型的3维框架,遴选30项具体指标(人均耕地面积、粮食单产、基尼系数等),构建粮食安全系统转型的评价指标体系,通过输入这些指标的数据,计算得到中国省域粮食安全子系统转型指数与系统综合指数,即中国粮食安全系统转型指数研究数据集(2000-2021)。该数据集内容包括31个省(直辖市、自治区)数据(香港、澳门、台湾数据暂缺):(1)粮食安全3个子系统的转型指数;(2)系统转型综合指数。数据集存储为.xlsx格式,由1个数据文件组成,数据量为53 KB。基于该数据集的研究论文发表在《地理学报》2024年79卷第9期。杨一单, 姚成胜*, 刘伟芳. 中国粮食安全系统转型指数研究数据集(2000-2021)[J/DB/OL]. 全球变化数据仓储电子杂志(中英文), 2025.

    西门子S7-1200PLC自定义堆栈FB块实现:先进先出与后进后出功能的数据管理程序

    内容概要:本文详细介绍了为西门子S7-1200 PLC开发的一个自定义堆栈程序。由于S7-1200未提供内置堆栈功能,作者使用SCL(Structured Control Language)编写了一个通用型堆栈功能块(FB),能够实现FIFO(先进先出)和LIFO(后进先出)的数据管理。该堆栈程序支持多种数据类型(如BOOL、REAL、DWORD等),并提供了入栈、出栈、清空等功能。文中还讨论了具体的实现细节,如边界检测、指针管理和环形缓冲区的设计,以及在实际工业环境中的应用效果。 适合人群:从事PLC编程、自动化控制系统开发的技术人员,尤其是熟悉西门子S7-1200系列PLC的工程师。 使用场景及目标:适用于需要临时存储和管理数据的应用场景,如生产线上的配方管理、设备故障回溯、日志记录等。通过自定义堆栈程序,可以提高数据处理效率,减少因缺乏内置堆栈功能而带来的不便。 其他说明:该堆栈程序已在实际生产环境中运行超过三个月,处理了大量数据,表现出良好的稳定性和性能。未来计划进一步优化,如改进为环形缓冲区以提升性能。

    直流有感无刷电机控制资料:多功能驱动器

    内容概要:本文详细介绍了专用于直流有感无刷电机的一款高性能驱动器。该驱动器不仅支持宽泛的电压与电流范围(9V-36V,5A),还提供多种输入信号形式(电位器、开关、PWM、RS485等)。其调速方式多样化,涵盖占空比调速、速度闭环控制和电流控制。此外,驱动器拥有霍尔自学习功能,能自动识别霍尔信号顺序,极大地简化了安装步骤。稳速控制响应迅速,能在1秒内完成正反转切换,且在极低速状态下仍能保持稳定运行。文中提供了多个Arduino和Python代码片段,展示了不同功能的具体实现方法。 适合人群:电机控制系统开发者、电子工程爱好者以及从事机器人、自动化设备等领域工作的工程师。 使用场景及目标:适用于小型设备、机器人、精密仪器等需要精准电机控制的场合。主要目标是帮助用户理解并掌握这款驱动器的特点,以便将其应用于实际项目中,提升系统的灵活性和可靠性。 其他说明:文章强调了驱动器在实际应用中的便捷性和高效性,特别是在霍尔自学习、稳速控制等方面的优势。同时,通过具体的代码实例,使读者更容易理解和实践这些功能。

    昆仑通态恒压供水PLC组态程序:三菱FX系列可靠运行,界面美观整洁的解决方案

    内容概要:本文详细介绍了使用昆仑通态MCGS组态软件和三菱FX3U PLC构建恒压供水系统的具体实现方法及其优化措施。主要内容涵盖HMI界面设计、PLC编程逻辑、PID控制参数整定、通信配置以及故障处理等方面。文中展示了多个关键代码片段,如压力设定值绑定、PID控制逻辑、水泵切换逻辑等,并分享了一些实用技巧,如动态水流效果、报警管理、压力波动处理等。此外,作者还强调了系统的可靠性和用户体验,通过实例证明了该方案在现场的实际表现。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对恒压供水系统感兴趣的从业者。 使用场景及目标:适用于需要设计和实施恒压供水系统的工程项目,旨在提高系统的稳定性、可靠性和易用性,同时降低维护成本并提升用户体验。 其他说明:文章提供了丰富的实战经验和代码示例,帮助读者更好地理解和掌握相关技术和应用场景。

    基于51单片机和LabVIEW的'虚拟GPS接收机'设计报告及源程序,可硬件实现

    内容概要:本文详细介绍了如何利用51单片机(STC89C52)和LabVIEW搭建一个能够运行的虚拟GPS接收机系统。硬件方面,主要讨论了单片机的选择、串口通信的稳定性以及电源管理等问题;软件方面,则着重讲解了NMEA-0183协议的解析、坐标生成算法及其在LabVIEW中的实现。此外,还探讨了一些常见的调试问题及解决方案,如波特率误差、数据解析错误等。通过该项目,读者不仅可以掌握GPS系统的原理,还能深入理解单片机编程和LabVIEW的应用。 适合人群:对嵌入式系统和GPS技术感兴趣的电子爱好者、学生及初级工程师。 使用场景及目标:① 学习51单片机的基础编程技能;② 掌握LabVIEW的基本使用方法;③ 理解GPS协议(NMEA-0183)的工作原理;④ 提升硬件电路设计能力,特别是串口通信和电源管理方面的经验。 其他说明:文中提供了详细的代码示例和调试技巧,帮助读者更好地理解和实现项目。同时,也鼓励读者进行进一步的创新和改进,如加入加速度计模块或支持更多类型的GPS协议。

    2023年软件结构化面试资料.doc

    2023年软件结构化面试资料.doc

    正弦波发生器电路仿真实验

    正弦波发生器电路仿真实验,选择LM417运算放大器进行实验,实现正弦波的生成

    GS276D:反激式隔离AC-DC开关电源设计(5V/2.4A)资料

    内容概要:本文详细介绍了基于GS276D芯片的5V/2.4A反激式隔离AC-DC开关电源设计方案。首先概述了电源的基本参数和特点,如输入电压范围为85-265VAC,输出为5V/2.4A,内置700V高压启动等功能。接着深入探讨了变压器设计、EMI优化、保护电路配置、动态峰值限制以及绿色模式下的节能措施等多个关键技术环节。文中提供了具体的计算方法、调试经验和优化技巧,如变压器初级电感量的计算、RC吸收电路的应用、过流保护的配置等。此外,还分享了许多实际调试过程中遇到的问题及其解决办法,如输出电压跳动、EMI超标等问题。 适合人群:具有一定电力电子基础的技术人员、电源设计师、硬件工程师。 使用场景及目标:适用于需要设计高效、稳定的反激式开关电源的场合,帮助工程师理解和掌握GS276D芯片的工作原理及应用技巧,提高产品性能和可靠性。 其他说明:文章不仅提供了详细的理论分析和技术指导,还结合了大量的实践经验,有助于读者更好地应对实际项目中的挑战。

    彩虹易支付最新升级版源码下载/BUG修复与订单投诉功能增强

    彩虹易支付最新升级版源码下载/BUG修复与订单投诉功能增强。该系统也没版本号,此版本目前是比较新的版本,增加了订单投诉功能,和一个好看的二次元模板。 此版本是全开源版,无一处加密文件

    灌装线自动化控制系统:SCL+顺控GRAPH西门子PLC1500,详解PLC和触摸屏程序,涵盖配方、报警记录、液位读取、重量读取,全程中文注释

    内容概要:本文详细介绍了西门子S7-1500 PLC平台上使用SCL(结构化控制语言)和GRAPH图形化编程工具来构建灌装生产线控制系统的方法。文中首先概述了系统的总体架构,包括主程序OB1作为调度中心,利用CASE语句进行模式切换,并确保模式间的平稳过渡。接着深入探讨了配方管理机制,采用结构体数组存储和验证配方参数,以及通过HMI界面方便地选择和修改配方。对于关键工序如灌装,则运用GRAPH绘制流程图,实现了更加直观易懂的状态转移逻辑,尤其强调了异常处理的灵活性。此外,针对传感器数据处理方面,提出了有效的滤波算法以提高测量精度。最后提及了报警日志的设计思路,即使用带有时间戳的环形队列记录故障信息,便于后期查询和诊断。同时,还分享了一些实用技巧,例如避免直接读写报警记录导致性能下降的问题。 适用人群:从事工业自动化领域的工程师和技术人员,尤其是那些正在或将要使用西门子PLC进行项目开发的人群。 使用场景及目标:适用于需要高效、可靠地完成复杂任务的制造业环境,特别是在食品饮料等行业中常见的灌装生产线。其目的是帮助开发者掌握如何结合SCL和GRAPH的优势,优化PLC编程,提升系统的响应速度、稳定性和可维护性。 其他说明:文章不仅提供了具体的编程实例,还分享了许多实践经验,有助于读者更好地理解和应用相关技术。

    b2c电子商务物流管理走向何方?.docx

    b2c电子商务物流管理走向何方?.docx

    FPGA以太网TCP IP协议栈源码分享:支持千兆、万兆速率,包含TOE技术,含ping、arp、igmp、udp、tcp及dhcp功能,适用于k7板卡测试工程,纯hdl移植便捷。

    内容概要:本文介绍了一款纯HDL实现的FPGA以太网TOE TCP/IP协议栈,支持千兆和万兆以太网,涵盖ping、arp、igmp、udp、tcp、dhcp等多种协议。该项目提供了清晰的代码结构,包括MAC层、IP层、TCP/UDP层、ARP、ICMP和DHCP模块,以及K7板卡的测试工程。代码实现简洁明了,便于移植到其他FPGA平台。文中详细介绍了各模块的工作原理,如ARP请求发送、Ping功能测试、TCP状态机等,并展示了其高效性和稳定性。此外,项目还提供了详细的移植指南,确保初学者也能轻松上手。 适合人群:对FPGA网络开发感兴趣的工程师和技术爱好者,尤其是有一定FPGA开发经验的人群。 使用场景及目标:适用于需要在网络设备中集成高效TCP/IP协议栈的应用场景,如嵌入式系统、网络加速设备等。目标是帮助开发者深入了解TCP/IP协议栈的工作机制,并提供一个高性能、易移植的解决方案。 其他说明:项目源码和文档齐全,可在GitHub上找到更多资源。文中提到的优化技巧和实际测试数据有助于进一步提升系统的性能和可靠性。

    2023年项目管理专升本阶段性作业.doc

    2023年项目管理专升本阶段性作业.doc

    idl_code_and_sample_data_for_computing_accuracy_metrics.zip

    计算融合图像(IDL 和 Python 代码)全方位性能评估(APA)指标及绘制 APA 图表的 R 代码

    西门子S7-1200 PLC编程实例:G120变频器与V90伺服驱动运动控制模板及HMI模板

    内容概要:本文详细介绍了基于西门子S7-1200 PLC、G120C变频器和V90伺服驱动的运动控制程序模板。涵盖了标准气缸块、G120C 352报文DP通信控制块、V90伺服控制写法、车型信息传递标准块以及配套的TP900 HMI模板五个主要部分。通过具体代码示例展示了各组件的工作原理及其在实际应用中的配置方法,帮助读者快速掌握这套系统的开发要点和技术细节。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些希望深入了解西门子S7-1200 PLC、G120C变频器和V90伺服驱动集成应用的专业人士。 使用场景及目标:适用于需要构建高效稳定的运动控制系统的企业和个人开发者。通过学习本模板,可以提高开发效率,减少重复劳动,同时确保系统的稳定性和可靠性。 其他说明:文中提到的所有代码片段均来自真实项目案例,具有很高的参考价值。此外,还提供了关于开发环境配置的重要提示,如TIA Portal版本要求等,有助于避免常见的安装和兼容性问题。

Global site tag (gtag.js) - Google Analytics