What is the difference between getResourceAsStream with and without getClassLoader?

前端 未结 3 1772
迷失自我
迷失自我 2021-02-19 19:50

I\'d like to know the difference between the following two:

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

and

相关标签:
3条回答
  • 2021-02-19 19:55

    From the Javadoc for Class.getResourceAsStream():

    This method delegates to this object's class loader. Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:

    • If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'.
    • Otherwise, the absolute name is of the following form: modified_package_name/name
      Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\u002e').

    In other words, they do the same thing if the "path" begins with a "/", but if not, then in the latter case, the path will be relative to the class's package, whereas the classloader one will be absolute.

    In short, the first fetches path/to/my/properties and the second fetches package/of/myclass/path/to/my/properties.

    0 讨论(0)
  • 2021-02-19 19:58

    The main practical difference is that you can use relative paths when you go through the class. So if your properties are in the same package as MyClass, you can do

    MyClass.class.getResourceAsStream("properties");
    
    0 讨论(0)
  • 2021-02-19 20:18

    From the Class.getClassLoader() documentation:

    Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader.

    So getClassLoader() may return null if the class was loaded by the bootstrap class loader, hence the null check in the Class.getResourceAsStream implementation:

    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);
    }
    

    You'll also note the statement name = resolveName(name); which Mark Peters has explained in his answer.

    0 讨论(0)
提交回复
热议问题