java getResource() 方法执行规律展示

结论

  1. getClassLoader().getResource(String s) 读取的是当前项目的根目录; getResource(String s) 读取的时 class类存在的目录
  2. getClassLoader().getResource(String s) 调用时, 传递参数开头不能包含斜杠(/), 否则读不到文件; getResource(String s) 调用时, 参数开头包含斜杠(/), 则从根目录开始读取(即: getResource("/") == getClassLoader().getResource("")), 不包含斜杠时, 读取类存在的目录
  3. 从根目录开始读文件时, 如果文件不存在, 则会去jar包中寻找文件, 再如果jar包中也不存在, 则返回null; 从class类存在的目录读取文件时, 如果不存在则直接返回null

结论性展示, 非展示原理

测试代码

/* 调用 getClassLoader() */
        // 读取当前项目的根目录
        System.out.println(HangTianDongLiUtil.class.getClassLoader().getResource(""));
        // 优先读取根目录下的文件; 如果文件不存在, 则会去jar包查找文件(!!!开头不能带/)
        System.out.println(HangTianDongLiUtil.class.getClassLoader().getResource("META-INF/NOTICE.txt"));
        // 带斜杠读取不到内容
        System.out.println(HangTianDongLiUtil.class.getClassLoader().getResource("/"));
        System.out.println(HangTianDongLiUtil.class.getClassLoader().getResource("/HangTianDongLiUtil.class"));
        System.out.println(HangTianDongLiUtil.class.getClassLoader().getResource("/META-INF/NOTICE.txt"));
        // 以流读取的规则也与上面的一致
        System.out.println(HangTianDongLiUtil.class.getClassLoader().getResourceAsStream("META-INF/NOTICE.txt"));
        System.out.println(HangTianDongLiUtil.class.getClassLoader().getResourceAsStream("/META-INF/NOTICE.txt"));
        System.out.println();
        /* 直接调用 getResource() */
        // 传入空字符串时, 返回的时传入的class的位置
        System.out.println(HangTianDongLiUtil.class.getResource(""));
        // 传入 / 时, 读取当前项目的根目录, 等同于 ==> getClassLoader().getResource()
        System.out.println(HangTianDongLiUtil.class.getResource("/"));

        // 读取根目录下的文件, 读不到会读 jar 包中的文件; 如果jar包中也找不到对应文件, 则返回null;
        System.out.println(HangTianDongLiUtil.class.getResource("/META-INF/NOTICE.txt"));
        System.out.println(HangTianDongLiUtil.class.getResource("/HangTianDongLiUtil.class"));
        // 查找class类下的文件, 找不到直接返回null, 不会去读取jar包
        System.out.println(HangTianDongLiUtil.class.getResource("META-INF/NOTICE.txt"));
        System.out.println(HangTianDongLiUtil.class.getResource("HangTianDongLiUtil.class"));
  1. 调用 getClassLoader().getResource()

    System.out.println(HangTianDongLiUtil.class.getClassLoader().getResource(""));
    

    执行结果: file:/E:/project/learning/myLogProject/build/classes/java/main/

    解释: 传入参数为空字符串时(""), 返回当前项目的根目录

    System.out.println(HangTianDongLiUtil.class.getClassLoader().getResource("META-INF/NOTICE.txt"));
    

    执行结果: jar:file:/D:/xx/local_jar/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-devtools/3.0.0/efb77f02a6312690c69049ad2bee06cab7a21a0f/spring-boot-devtools-3.0.0.jar!/META-INF/NOTICE.txt

    解释: 传入参数为不带'/'的字符串时, 从根目录查找文件; 如果找不到, 则会从jar包中查找

以下为测试代码的全部测试结果 ↓

file:/E:/project/learning/myLogProject/build/classes/java/main/
jar:file:/D:/zq/local_jar/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-devtools/3.0.0/efb77f02a6312690c69049ad2bee06cab7a21a0f/spring-boot-devtools-3.0.0.jar!/META-INF/NOTICE.txt
null
null
null
sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@4c163e3
null

file:/E:/project/learning/myLogProject/build/classes/java/main/com/myproject/mylogproject/main/
file:/E:/project/learning/myLogProject/build/classes/java/main/
jar:file:/D:/zq/local_jar/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-devtools/3.0.0/efb77f02a6312690c69049ad2bee06cab7a21a0f/spring-boot-devtools-3.0.0.jar!/META-INF/NOTICE.txt
null
null
file:/E:/project/learning/myLogProject/build/classes/java/main/com/myproject/mylogproject/main/HangTianDongLiUtil.class
posted @ 2023-01-11 15:48  浅唱z2  阅读(82)  评论(0编辑  收藏  举报