Diferencia entre getClass (). GetClassLoader (). GetResource () y getClass.getResource ()?

Al recuperar archivos de recursos, ¿cuál debo usar en qué circunstancias?

El segundo llama al primero. La diferencia se describe en el javadoc.

La primera toma rutas que no comienzan con a / , y siempre comienza en la raíz de la ruta de clases.

El segundo toma un camino que puede comenzar con a / . Si lo hace, comienza en la raíz de la ruta de clase. Si no, comienza en el paquete de la clase en la que se llama el método.

Entonces getClass().getClassLoader().getResource("foo/bar.txt") es equivalente a getClass().getResource("/foo/bar.txt") .

Y, suponiendo que getClass () devuelva una clase que está en el paquete foo , getClass().getResource("bar.txt") es equivalente a getClass().getClassLoader().getResource("foo/bar.txt")

¿Cuál debería usar en qué circunstancias?

Ninguno. Debería llamar a Thread.currentThread().getContextClassLoader() .

Esto tiene el beneficio de no necesitar ser cambiado dependiendo de si está llamando desde un método estático o de instancia.

Y, lo que es más importante, manejará adecuadamente la delegación del cargador de clases dentro de un contenedor. Si no lo usa, puede encontrar que no se encuentra un recurso de “aplicación” porque la clase que lo está cargando fue cargada por un cargador de clases más arriba en la jerarquía de la delegación.

Básicamente, Class.getResource() permite especificar una ruta relativa al paquete de la clase, mientras que ClassLoader.getResource() siempre es una ruta “absoluta”.

Asi que:

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

es equivalente a:

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

y ambos son equivalentes a:

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

(Asumiendo some.Other y foo.bar.Baz son cargados por el mismo cargador de clases, por supuesto).