Gostaria de saber a melhor forma de carregar um recurso em Java:
this.getClass().getResource() (or getResourceAsStream())
,Thread.currentThread().getContextClassLoader().getResource(name)
,System.class.getResource(name)
.
Encontre a solução de acordo com o que você deseja ...
Há duas coisas que getResource
/ getResourceAsStream()
obterá da classe em que é chamado ...
Então se você fizer
this.getClass().getResource("foo.txt");
ele tentará carregar foo.txt do mesmo pacote da classe "this" e com o carregador de classes da classe "this". Se você colocar um "/" na frente, estará fazendo uma referência absoluta ao recurso.
this.getClass().getResource("/x/y/z/foo.txt")
irá carregar o recurso do carregador de classes de "this" e do pacote xyz (ele precisará estar no mesmo diretório que as classes desse pacote).
Thread.currentThread().getContextClassLoader().getResource(name)
irá carregar com o carregador de classes de contexto, mas não resolverá o nome de acordo com qualquer pacote (deve ser absolutamente referenciado)
System.class.getResource(name)
Carregará o recurso com o carregador de classes do sistema (também teria que ser absolutamente referenciado, pois você não poderá colocar nada no pacote java.lang (o pacote de System).
Basta dar uma olhada na fonte. Também indica que getResourceAsStream apenas chama "openStream" no URL retornado de getResource e retorna isso.
Thread#setContextClassLoader
. Isso é útil se você precisar modificar o caminho de classe enquanto o programa está sendo executado.Bem, isso depende parcialmente do que você deseja que aconteça se estiver realmente em uma classe derivada.
Por exemplo, suponha que
SuperClass
está em A.jar eSubClass
em B.jar, e você está executando o código em um método de instância declarado em,SuperClass
mas ondethis
se refere a uma instância deSubClass
. Se você usá-this.getClass().getResource()
lo, terá uma aparência relativa aSubClass
, em B.jar. Eu suspeito que geralmente não é o que é necessário.Pessoalmente, eu provavelmente usaria com
Foo.class.getResourceAsStream(name)
mais frequência - se você já sabe o nome do recurso que está procurando e tem certeza de onde ele está relacionadoFoo
, essa é a maneira mais robusta de fazê-lo IMO.É claro que há momentos em que você também não quer isso: julgue cada caso pelos seus méritos. É apenas o "Eu sei que este recurso vem junto com esta classe" é o mais comum que encontrei.
fonte
this.getClass()
. Crie uma instância da subclasse e chame o método ... ele imprimirá o nome da subclasse, não da superclasse.Eu procuro três lugares como mostrado abaixo. Comentários são bem-vindos.
fonte
Eu sei que é muito tarde para outra resposta, mas eu só queria compartilhar o que me ajudou no final. Ele também carregará recursos / arquivos do caminho absoluto do sistema de arquivos (não apenas do caminho de classe).
fonte
Tentei várias maneiras e funções sugeridas acima, mas não funcionaram no meu projeto. De qualquer forma, encontrei a solução e aqui está:
fonte
this.getClass().getResourceAsStream()
neste caso. Se vocêgetResourceAsStream
der uma olhada na fonte do método, notará que ele faz a mesma coisa que você, mas de uma forma mais inteligente (fallback se nenhumClassLoader
for encontrado na classe). Ele também indica que você pode encontrar um potencialnull
emgetClassLoader
em seu código ...this.getClass().getResourceAsStream()
não está funcionando para mim, então eu uso isso funciona. Acho que existem algumas pessoas que podem enfrentar problemas como o meu.