What is the difference between Class.getResource() and ClassLoader.getResource()?

前端 未结 7 1875
情歌与酒
情歌与酒 2020-11-22 02:25

I wonder what the difference is between Class.getResource() and ClassLoader.getResource()?

edit: I especially want to know if any cachi

相关标签:
7条回答
  • 2020-11-22 03:05

    All these answers around here, as well as the answers in this question, suggest that loading absolute URLs, like "/foo/bar.properties" treated the same by class.getResourceAsStream(String) and class.getClassLoader().getResourceAsStream(String). This is NOT the case, at least not in my Tomcat configuration/version (currently 7.0.40).

    MyClass.class.getResourceAsStream("/foo/bar.properties"); // works!  
    MyClass.class.getClassLoader().getResourceAsStream("/foo/bar.properties"); // does NOT work!
    

    Sorry, I have absolutely no satisfying explanation, but I guess that tomcat does dirty tricks and his black magic with the classloaders and cause the difference. I always used class.getResourceAsStream(String) in the past and haven't had any problems.

    PS: I also posted this over here

    0 讨论(0)
  • 2020-11-22 03:15

    Class.getResources would retrieve the resource by the classloader which load the object. While ClassLoader.getResource would retrieve the resource using the classloader specified.

    0 讨论(0)
  • 2020-11-22 03:20

    Had to look it up in the specs:

    • Class.getResource(String resource)

    • ClassLoader.getResource(String resource)

    Class's getResource() - documentation states the difference:

    This method delegates the call to its class loader, after making these changes to the resource name: if the resource name starts with "/", it is unchanged; otherwise, the package name is prepended to the resource name after converting "." to "/". If this object was loaded by the bootstrap loader, the call is delegated to ClassLoader.getSystemResource.

    0 讨论(0)
  • 2020-11-22 03:21

    I tried reading from input1.txt which was inside one of my packages together with the class which was trying to read it.

    The following works:

    String fileName = FileTransferClient.class.getResource("input1.txt").getPath();
    
    System.out.println(fileName);
    
    BufferedReader bufferedTextIn = new BufferedReader(new FileReader(fileName));
    

    The most important part was to call getPath() if you want the correct path name in String format. DO NOT USE toString() because it will add some extra formatting text which will TOTALLY MESS UP the fileName (you can try it and see the print out).

    Spent 2 hours debugging this... :(

    0 讨论(0)
  • 2020-11-22 03:22

    The first call searches relative to the .class file while the latter searches relative to the classpath root.

    To debug issues like that, I print the URL:

    System.out.println( getClass().getResource(getClass().getSimpleName() + ".class") );
    
    0 讨论(0)
  • 2020-11-22 03:24

    Class.getResource can take a "relative" resource name, which is treated relative to the class's package. Alternatively you can specify an "absolute" resource name by using a leading slash. Classloader resource paths are always deemed to be absolute.

    So the following are basically equivalent:

    foo.bar.Baz.class.getResource("xyz.txt");
    foo.bar.Baz.class.getClassLoader().getResource("foo/bar/xyz.txt");
    

    And so are these (but they're different from the above):

    foo.bar.Baz.class.getResource("/data/xyz.txt");
    foo.bar.Baz.class.getClassLoader().getResource("data/xyz.txt");
    
    0 讨论(0)
提交回复
热议问题