It is always a ClassLoader that ends up doing the work that finds a resource and makes it available to your code. But you don't immediately have access to a ClassLoader instance necessarily. If you do, and you know that's the right ClassLoader to use, then you should go ahead and use it directly by calling the getResource() method on it.
Using <Class instance>.getResource() is usually a more direct and "smarter" way to get the behavior you want. It does a number of different things to determine the correct ClassLoader to use to do the lookup. Then it ends up calling <ClassLoader instance>.getResource() or one of its cousin methods (like ClassLoader.getSystemResource()) to do the lookup of the resource. Since you always have access to A class, and you usually have access to THE class with which a resource is associated, it's more convenient to call <Class instance>.getResource() and let the system do the work of finding the appropriate ClassLoader to use.
NOTE: In cases not involving modules, <Class instance>.getResource() is often equivalent to <Class instance>.getClassLoader().getResource(). But not all classes have an associated ClassLoader. Calling the Class version of getResource() will use the system ClassLoader if the class itself does not have an associated ClassLoader.