Chciałbym poznać najlepszy sposób ładowania zasobu w Javie:
this.getClass().getResource() (or getResourceAsStream())
,Thread.currentThread().getContextClassLoader().getResource(name)
,System.class.getResource(name)
.
Opracuj rozwiązanie zgodnie z tym, co chcesz ...
Są dwie rzeczy, które getResource
/ getResourceAsStream()
otrzyma od klasy, do której się odwołuje ...
Więc jeśli tak
this.getClass().getResource("foo.txt");
spróbuje załadować foo.txt z tego samego pakietu co klasa „this” oraz z programem ładującym klasy „this”. Jeśli umieścisz znak „/” na początku, odwołujesz się do zasobu.
this.getClass().getResource("/x/y/z/foo.txt")
załaduje zasób z programu ładującego klasy „this” iz pakietu xyz (będzie musiał znajdować się w tym samym katalogu, co klasy w tym pakiecie).
Thread.currentThread().getContextClassLoader().getResource(name)
załaduje się za pomocą programu ładującego klasy kontekstu, ale nie rozwiąże nazwy zgodnie z żadnym pakietem (musi być bezwzględnie przywoływany)
System.class.getResource(name)
Załaduje zasób za pomocą programu ładującego klasy systemowe (musiałby również być bezwzględnie odwołany, ponieważ nie będziesz w stanie umieścić niczego w pakiecie java.lang (pakiet System).
Spójrz tylko na źródło. Wskazuje również, że getResourceAsStream po prostu wywołuje „openStream” w adresie URL zwróconym przez getResource i zwraca go.
Thread#setContextClassLoader
. Jest to przydatne, jeśli chcesz zmodyfikować ścieżkę klasy podczas wykonywania programu.Cóż, częściowo zależy to od tego, co chcesz, aby się wydarzyło, jeśli faktycznie jesteś w klasie pochodnej.
Na przykład załóżmy, że
SuperClass
znajduje się w A.jar iSubClass
B.jar, a wykonujesz kod w metodzie instancji zadeklarowanej w,SuperClass
ale gdziethis
odnosi się do wystąpieniaSubClass
. Jeśli używaszthis.getClass().getResource()
, będzie wyglądać w stosunku doSubClass
, w B.jar. Podejrzewam, że zwykle nie jest to wymagane.Osobiście prawdopodobnie
Foo.class.getResourceAsStream(name)
używałbym najczęściej - jeśli znasz już nazwę zasobu, którego szukasz, i jesteś pewien, gdzie jest ona w stosunku doFoo
, jest to najbardziej solidny sposób zrobienia tego IMO.Oczywiście są chwile, kiedy nie tego też chcesz: oceniaj każdy przypadek na podstawie jego meritum. To po prostu „Wiem, że ten zasób jest dołączony do tej klasy” jest najczęstszym, na jaki się natknąłem.
źródło
this.getClass()
. Utwórz instancję podklasy i wywołaj metodę ... wydrukuje nazwę podklasy, a nie nadklasy.Przeszukuję trzy miejsca, jak pokazano poniżej. Komentarze mile widziane.
źródło
Wiem, że jest naprawdę późno na inną odpowiedź, ale chciałem tylko podzielić się tym, co pomogło mi na końcu. Załaduje również zasoby / pliki z bezwzględnej ścieżki systemu plików (nie tylko ścieżki klas).
źródło
Wypróbowałem wiele sposobów i funkcji, które zasugerowałem powyżej, ale nie zadziałały w moim projekcie. Tak czy inaczej znalazłem rozwiązanie i oto jest:
źródło
this.getClass().getResourceAsStream()
tym przypadku powinieneś lepiej użyć . Jeśli przyjrzysz się źródługetResourceAsStream
metody, zauważysz, że robi to samo co ty, ale w sprytniejszy sposób (jeśli nieClassLoader
można znaleźć w klasie). Wskazuje również, że można napotkać potencjałnull
nagetClassLoader
w kodzie ...this.getClass().getResourceAsStream()
nie działa dla mnie, więc używam tego. Myślę, że są ludzie, którzy mogą zmierzyć się z takim problemem jak mój.