在加载.jar资源时使用ClassLoader

时间:2016-05-15 02:44:26

标签: java java-8 classloader

我只是不明白为什么使用ClassLoader会导致这两种情况采取不同的行动。有人可以解释ClassLoader如何/为什么更改搜索,以便它需要一个完整的路径进入jar?

package com.example;
import java.io.InputStream;

public class SomeClass {
  private static InputStream stm;
  static {
    for (final String s : new String[] { "file.png", "com/example/file.png", "/com/example/file.png" }) {
      // case 1 - w/o classLoader
      stm = SomeClass.class.getResourceAsStream(s);
      System.out.println("w/o          : " + (stm == null ? "FAILED to load" : "loaded") + " " + s);

      // case 2 - w/ classLoader
      stm = SomeClass.class.getClassLoader().getResourceAsStream(s);
      System.out.println("w/classloader: " + (stm == null ? "FAILED to load" : "loaded") + " " + s);
    }
  }

  public static void main(final String args[]) {}
}

产地:

w/o          : loaded file.png
w/classloader: FAILED to load file.png
w/o          : FAILED to load com/example/file.png
w/classloader: loaded com/example/file.png
w/o          : loaded /com/example/file.png
w/classloader: FAILED to load /com/example/file.png

1 个答案:

答案 0 :(得分:4)

因为路径的评估方式不同,具体取决于您调用的com.example.SomeClass方法 如果您在课程SomeClass上致电Class.getResourceAsStream(),那么如果路径不以/开头,则会相对于file.png评估路径,因此/com/example/file.png变为{ {1}}和com/example/file.png成为/com/example/com/example/file.png 如果您在ClassLoader上拨打ClassLoader.getResourceAsStream(),则该路径是隐式绝对的,不得以/开头,因此file.png变为/file.png并{{1变成com/example/file.png
如果您使用/com/example/file.png之类的绝对路径,则必须使用/com/example/file.png方法。

不幸的是Class的隐含绝对性仅在ClassLoader.getResourceAsStream()的文档中隐式记录,该文档声明它在委托给Class.getResourceAsStream()方法之前删除了前导斜杠。