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

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

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

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.