Mode de chargement préféré des ressources en Java

Je voudrais connaître le meilleur moyen de charger une ressource en Java:

  • this.getClass().getResource() (or getResourceAsStream()) ,
  • Thread.currentThread().getContextClassLoader().getResource(name) ,
  • System.class.getResource(name) .

Déterminez la solution en fonction de ce que vous voulez …

Il y a deux choses que getResource / getResourceAsStream() obtiendra de la classe sur laquelle il est appelé …

  1. Le chargeur de classe
  2. L’emplacement de départ

Donc si vous le faites

 this.getClass().getResource("foo.txt"); 

il tentera de charger foo.txt à partir du même paquet que la classe “this” et avec le chargeur de classe de la classe “this”. Si vous mettez un “/” devant vous, vous faites absolument référence à la ressource.

 this.getClass().getResource("/x/y/z/foo.txt") 

chargera la ressource à partir du chargeur de classes de “this” et du paquet xyz (il devra être dans le même répertoire que les classes de ce paquet).

 Thread.currentThread().getContextClassLoader().getResource(name) 

chargera avec le chargeur de classe de contexte mais ne résoudra pas le nom selon n’importe quel paquet (il doit être absolument référencé)

 System.class.getResource(name) 

Va charger la ressource avec le chargeur de classe système (il devrait également être référencé, car vous ne pourrez rien insérer dans le paquetage java.lang (le paquetage du système).

Il suffit de regarder la source. Indique également que getResourceAsStream appelle simplement “openStream” sur l’URL renvoyée par getResource et la renvoie.

Eh bien, cela dépend en partie de ce que vous voulez faire si vous vous trouvez dans une classe dérivée.

Par exemple, supposons que SuperClass trouve dans A.jar et que SubClass trouve dans B.jar et que vous exécutez du code dans une méthode d’instance déclarée dans SuperClass mais que this fait référence à une instance de SubClass . Si vous utilisez this.getClass().getResource() cela ressemblera à SubClass , dans B.jar. Je pense que ce n’est généralement pas ce qui est requirejs.

Personnellement, j’utiliserais probablement Foo.class.getResourceAsStream(name) plus souvent – si vous connaissez déjà le nom de la ressource que vous recherchez, et que vous êtes sûr de son emplacement par rapport à Foo , c’est le moyen le plus robuste de le faire à l’OMI.

Bien sûr, il y a des moments où ce n’est pas ce que vous voulez: juger chaque cas sur le fond. C’est juste le “Je sais que cette ressource est fournie avec cette classe” est la plus courante que j’ai rencontrée.

Je recherche trois endroits comme indiqué ci-dessous. Les commentaires sont les bienvenus.

 public URL getResource(Ssortingng resource){ URL url ; //Try with the Thread Context Loader. ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if(classLoader != null){ url = classLoader.getResource(resource); if(url != null){ return url; } } //Let's now try with the classloader that loaded this class. classLoader = Loader.class.getClassLoader(); if(classLoader != null){ url = classLoader.getResource(resource); if(url != null){ return url; } } //Last ditch attempt. Get the resource from the classpath. return ClassLoader.getSystemResource(resource); } 

Je le sais très tard pour une autre réponse mais je voulais juste partager ce qui m’a aidé à la fin. Il va également charger des ressources / fichiers à partir du chemin absolu du système de fichiers (pas seulement celui du classpath).

 public class ResourceLoader { public static URL getResource(Ssortingng resource) { final List classLoaders = new ArrayList(); classLoaders.add(Thread.currentThread().getContextClassLoader()); classLoaders.add(ResourceLoader.class.getClassLoader()); for (ClassLoader classLoader : classLoaders) { final URL url = getResourceWith(classLoader, resource); if (url != null) { return url; } } final URL systemResource = ClassLoader.getSystemResource(resource); if (systemResource != null) { return systemResource; } else { try { return new File(resource).toURI().toURL(); } catch (MalformedURLException e) { return null; } } } private static URL getResourceWith(ClassLoader classLoader, Ssortingng resource) { if (classLoader != null) { return classLoader.getResource(resource); } return null; } } 

J’ai essayé de nombreuses manières et fonctions suggérées ci-dessus, mais elles n’ont pas fonctionné dans mon projet. En tout cas j’ai trouvé une solution et la voici:

 try { InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png"); img = ImageIO.read(path); } catch (IOException e) { e.printStackTrace(); }