有和没有getClassLoader的getResourceAsStream有什么区别?

我想知道以下两者之间的区别:

MyClass.class.getClassLoader().getResourceAsStream("path/to/my/properties");

MyClass.class.getResourceAsStream("path/to/my/properties");

谢谢。

从Javadoc for Class.getResourceAsStream()

此方法委托给该对象的类加载器。 在委派之前,使用此算法从给定资源名称构造绝对资源名称:

  • 如果name以’/’(’\ u002f’)开头,则资源的绝对名称是’/’后面的名称部分。
  • 否则,绝对名称的格式如下: modified_package_name/name
    其中modified_pa​​ckage_name是此对象的包名称,其中’/’替换为’。’ ( ‘\ u002e’)。

换句话说,如果“path”以“/”开头,它们会做同样的事情,但如果没有,那么在后一种情况下,路径将相对于类的包,而类加载器将是绝对的。

简而言之,第一个获取path/to/my/properties ,第二个获取package/of/myclass/path/to/my/properties

Class.getClassLoader() 文档 :

返回类的类加载器。 某些实现可能使用null来表示引导类加载器。 如果此类由引导类加载器加载,则此方法将在此类实现中返回null。

因此,如果类由引导类加载器加载,则getClassLoader() 可能返回null ,因此在Class.getResourceAsStream 实现中进行空检查:

 public InputStream getResourceAsStream(String name) { name = resolveName(name); ClassLoader cl = getClassLoader0(); if (cl==null) { // A system class. return ClassLoader.getSystemResourceAsStream(name); } return cl.getResourceAsStream(name); } 

您还会注意到语句name = resolveName(name); Mark Peters在他的回答中解释道。

主要的实际区别在于,您可以在课程中使用相对路径。 因此,如果您的属性与MyClass位于同一个包中,则可以执行此操作

 MyClass.class.getResourceAsStream("properties");