101 votes

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

J'aimerais 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) .

135voto

Michael Wiles Points 7570

Le travail de la solution en fonction de ce que vous voulez...

Il y a deux choses que getResource/getResourceAsStream() de la classe à laquelle il est appelé...

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

Donc, si vous ne

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

il va tenter de charger foo.txt à partir de la même formule que le "il" de la classe et avec le chargeur de classe de la "ce" de la classe. Si vous mettez un "/" devant alors vous êtes absolument référencer la ressource.

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

va charger la ressource à partir de la classe loader de "ce" et de la "x".y.z paquet (il devra être dans le même répertoire que les classes de ce package).

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

charge avec le contexte de la classe loader, mais ne permettra pas de résoudre le nom selon l'une quelconque paquet (il doit être absolument référencé)

System.class.getResource(name)

Va charger la ressource avec le système de chargeur de classe (il devrait être absolument référencé en tant que bien, car vous ne serez pas en mesure de mettre n'importe quoi dans le java.lang package (le package de Système).

Il suffit de prendre un coup d'oeil à la source. Indique également que getResourceAsStream appelle simplement "openStream" sur l'URL renvoyée à partir de getResource et des rendements.

14voto

Jon Skeet Points 692016

Eh bien, en partie dépend de ce que vous voulez faire si vous êtes réellement dans une classe dérivée.

Par exemple, supposons SuperClass est en A.jar et SubClass est en B.jar et vous êtes à l'exécution de code dans une méthode d'instance a déclaré en SuperClass mais où this fait référence à une instance d' SubClass. Si vous utilisez this.getClass().getResource() il va chercher par rapport à l' SubClass, dans B.jar. Je pense que c'est généralement pas ce qui est nécessaire.

Personnellement, je serais probablement utiliser Foo.class.getResourceAsStream(name) le plus souvent - si vous connaissez déjà le nom de la ressource que vous êtes après, et vous êtes sûr de l'endroit où elle est relative à l' Foo, c'est le plus robuste de la façon de faire de l'OMI.

Bien sûr, il ya des moments où c'est pas ce que vous voulez: juger chaque cas selon ses mérites. C'est juste le "je sais que cette ressource est livré avec cette classe" est la plus commune que j'ai pu croiser.

10voto

dogbane Points 85749

Je recherche trois endroits comme indiqué ci-dessous. Commentaires bienvenus.

 public URL getResource(String 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);
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X