73

What is the difference between getClass().getClassLoader().getResource() and getClass.getResource()?

When retrieving files from resources, which one should I use in what circumstances?

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Jimmy C
  • 9,270
  • 11
  • 44
  • 64
  • 1
    See http://stackoverflow.com/questions/676250/different-ways-of-loading-a-file-as-an-inputstream – Reimeus Feb 06 '13 at 21:55
  • Basically (from the question @Reimeus linked) the way the relative path lookups work. `Class.getResource` looks it up relative to the class's package, and `ClassLoader.getResource` doesn't. – Brian Feb 06 '13 at 21:57

3 Answers3

77

The second one calls the first one. The difference is described in the javadoc.

The first one takes paths that don't start with a /, and always starts at the root of the classpath.

The second one takes path that can start with a /. If it does, it starts at the root of the classpath. If not, it starts at the package of the class on which the method is called.

So getClass().getClassLoader().getResource("foo/bar.txt") is equivalent to getClass().getResource("/foo/bar.txt").

And, assuming getClass() returns a class that is in the package foo, getClass().getResource("bar.txt") is equivalent to getClass().getClassLoader().getResource("foo/bar.txt")

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • thanks for the answer. suggestion: instead of "first one", "second one", you could have updated the answer little bit more readable. – RamPrakash Aug 07 '23 at 22:32
34

which one should I use in what circumstances?

Neither. You should call Thread.currentThread().getContextClassLoader().

This has the benefit of not needing to be changed depending on whether you're calling from a static or instance method.

And more important, it will properly handle classloader delegation inside a container. If you don't use it, you might find that an "application" resource isn't found because the class that's loading it was loaded by a classloader higher up the delegation hierarchy.

parsifal
  • 431
  • 3
  • 2
11

Basically, Class.getResource() allows you to specify a path relative to the package of the class, whereas ClassLoader.getResource() is always an "absolute" path.

So:

foo.bar.Baz.class.getResource("data.txt")

is equivalent to:

some.Other.class.getResource("/foo/bar/data.txt")

and they're both equivalent to:

some.Other.class.getClassLoader().getResource("foo/bar/data.txt")

(Assuming some.Other and foo.bar.Baz are loaded by the same classloader, of course.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194