博客
关于我
Java加载资源文件时的路径问题
阅读量:794 次
发布时间:2023-01-28

本文共 2183 字,大约阅读时间需要 7 分钟。

在学习Java类加载机制时,资源文件的路径问题经常会让人困惑。特别是在Tomcat加载Servlet以及处理资源文件时,了解如何有效地加载资源是至关重要的。资源文件可以是任何类型的文件,包括XML、properties、图片等。那么,如何正确地进行资源文件的加载呢?下面详细探讨一下两种主要的方法。

一、使用ClassLoader加载资源文件

在Java应用中,ClassLoader是一个非常重要的概念。它负责根据类路径(CLASSPATH)或JAR文件中的路径来加载类和资源。ClassLoader主要有三种类型:

  • 根类加载器(Bootstrap ClassLoader)

    这是由C++编写的稳定的类加载器。它负责加载JRE(Java Runtime Environment)中的一些核心类,如java.lang.Object和其他运行时所需的类。根类加载器负责加载的包路径为:BootstrapClassloader -> JRE/lib/rt.jar

  • 扩展类加载器(ExtClassLoader)

    这是由Java编写的扩展类加载器。它专门负责加载JRE中扩展包中的类。扩展类加载器负责加载的包路径为:ExtClassLoader -> JRE/lib/ext/*.jar

  • 应用类加载器(AppClassLoader)或系统类加载器

    这是负责加载用户应用中所依赖的类的加载器。通过调用ClassLoader.getSystemClassLoader()可以获取应用类加载器。它负责将CLASSPATH中的类加载到内存中。

  • 类加载器之间并非采用垂直的父子关系,而是一种组合关系。这意味着我们可以通过在类加载器的构造函数中传入父类加载器的实例来实现成层装载。例如,可以构造一个自定义的类加载器,将根类加载器或应用类加载器作为其父加载器。

    关于类加载器的继承关系

    类加载器的继承关系并不是传统的单向父子关系,而是通过将不同的加载器“串起来”,形成一种复合关系。这意味着,类加载器在装载类时,会依次委派给其子类加载器,直到某个类加载器能够实际装载该类。

    如何获取应用类加载器

    为了获取应用类加载器,我们可以调用ClassLoader.getSystemClassLoader()方法。它返回的是应用当前类加载器的实例,也就是系统类加载器。

    使用ClassLoader加载资源文件

    有一点需要注意的是,ClassLoader看待资源文件的方式与类的方式有明显区别。如果你想通过ClassLoader来加载资源文件,可以使用ClassLoader.getResource(String)方法。资源文件的路径有两种形式:

  • 相对路径:资源文件位于类路径的某个子目录下。此时,路径不需要以斜杠/开头。

    例如,假设资源文件names.ser位于Demo类所在的目录下的demo包中,路径应写成Demo.class.getResource("names.ser")
    但是如果需要加载外部文件,比如先前提到的demo/names.ser,必须使用以下方式。

  • 绝对路径:资源文件位于类路径之外,也就是说不位于任何包内。这时,你必须在路径前加上一个斜杠/,例如:URL url = getSystemClassLoader().getResource("/demo/names.ser");

  • 需要注意的是,忘记在类路径外的资源前加斜杜带将导致资源无法被找到。这个细节经常会让开发者困扰。

    关于Class.getResource方法

    Class提供了getResource()方法,它可以通过当前类的类加载器来获取资源文件。通过查看Class类源码,我们可以看出这个方法实际上会调用当前类的类加载器(调用getClassLoader())来获取资源文件。

    此外,Class类的resolveName()方法负责将资源文件的路径进行适当的转换。例如,假设你试图获取package reflects next.java中的资源文件res, 你需要注意路径如何处理。如果路径不以/开头,Class类会尝试将当前类的包路径添加到资源路径中。

    比如,假设你有一个类com.example.Demo1,它位于com.example包中。你可以通过以下方式加载com.example包下的资源文件names.ser

    URL resource = Demo1.class.getResource("names.ser");

    如果你想要加载位于类路径之外的结构化资源文件,可以通过在路径前加上斜杠:

    URL resource = Demo1.class.getResource("/com/example/names.ser");

    理解了这些实现机制后,就可以在实际应用中灵活处理资源文件的路径问题。无论是通过ClassLoader直接获取资源文件,还是通过Class.getResource方法进行间接调用,最终目标都是通过类加载器的机制来定位和加载所需的资源文件。

    通过以上分析,我们可以清晰地看到,Java中的形状加载机制是在类路径或JAR文件中寻找资源文件,最终由类加载器进行解释和加载。无论是内置的ClassLoader还是自定义的类加载器,掌握它们的工作原理都是解决资源加载问题的关键。

    转载地址:http://gjryk.baihongyu.com/

    你可能感兴趣的文章
    echarts 基本图表开发小结
    查看>>
    TreeSet、TreeMap
    查看>>
    JVM内存模型
    查看>>
    可变长度参数
    查看>>
    GitHub上传时,项目在已有文档时直接push出现错误解决方案
    查看>>
    嵌入式系统试题库(CSU)
    查看>>
    00010.02最基础客户信息管理软件(意义类的小项目,练习基础,不涉及数据库)
    查看>>
    00013.05 字符串比较
    查看>>
    SpringCloud-Eureka报错 Error creating bean with name解决
    查看>>
    UE4 错误列表 error码(只记录我遇到的情况,持续添加,未完成)
    查看>>
    cmd编译.java文件 : java:720: 错误: 编码GBK的不可映射字符 Why ? ? ? ?
    查看>>
    Android 架构组件 – 让天下没有难做的 App
    查看>>
    能解决数据可视化大屏需求的3款可视化工具
    查看>>
    第01问:MySQL 一次 insert 刷几次盘?
    查看>>
    Android 开发常用的工具类(更新ing)
    查看>>
    Python爬虫训练:爬取酷燃网视频数据
    查看>>
    解决微信小程序项目导入的问题:app.json 未找到、 __wxConfig is not defined
    查看>>
    非迅捷|PDF、Word、PPT、Excel、图片等互相在线转换:免费、简单、快速、零错误、无套路
    查看>>
    laravel server error 服务器内部错误
    查看>>
    一道简单的访问越界、栈溢出pwn解题记录
    查看>>