Ich möchte wissen, wie eine Ressource am besten in Java geladen werden kann:
this.getClass().getResource() (or getResourceAsStream())
,Thread.currentThread().getContextClassLoader().getResource(name)
,System.class.getResource(name)
.
Erarbeiten Sie die Lösung nach Ihren Wünschen ...
Es gibt zwei Dinge , die getResource
/ getResourceAsStream()
aus der Klasse erhalten wird er am genannt wird ...
Also wenn du es tust
this.getClass().getResource("foo.txt");
Es wird versucht, foo.txt aus demselben Paket wie die "this" -Klasse und mit dem Klassenladeprogramm der "this" -Klasse zu laden. Wenn Sie ein "/" voranstellen, verweisen Sie absolut auf die Ressource.
this.getClass().getResource("/x/y/z/foo.txt")
lädt die Ressource aus dem Klassenlader von "this" und aus dem xyz-Paket (sie muss sich im selben Verzeichnis wie die Klassen in diesem Paket befinden).
Thread.currentThread().getContextClassLoader().getResource(name)
wird mit dem Kontextklassenlader geladen, löst den Namen jedoch nicht gemäß einem Paket auf (es muss unbedingt referenziert werden)
System.class.getResource(name)
Lädt die Ressource mit dem Systemklassenlader (es müsste auch unbedingt referenziert werden, da Sie nichts in das Paket java.lang (das Paket von System) einfügen können.
Schauen Sie sich einfach die Quelle an. Gibt außerdem an, dass getResourceAsStream nur "openStream" für die von getResource zurückgegebene URL aufruft und diese zurückgibt.
Thread#setContextClassLoader
. Dies ist nützlich, wenn Sie den Klassenpfad ändern müssen, während das Programm ausgeführt wird.Nun, es hängt teilweise davon ab, was passieren soll, wenn Sie tatsächlich in einer abgeleiteten Klasse sind.
Angenommen, es
SuperClass
befindet sich in A.jar undSubClass
in B.jar, und Sie führen Code in einer Instanzmethode aus, die in deklariert istSuperClass
, wobeithis
sich jedoch auf eine Instanz von beziehtSubClass
. Wenn Sie es verwendenthis.getClass().getResource()
, wird es relativ zuSubClass
, in B.jar aussehen. Ich vermute, dass dies normalerweise nicht erforderlich ist.Persönlich würde ich wahrscheinlich
Foo.class.getResourceAsStream(name)
am häufigsten verwenden - wenn Sie den Namen der Ressource, nach der Sie suchen, bereits kennen und sicher sind, wo er sich relativFoo
befindet, ist dies die robusteste Methode, dies IMO zu tun.Natürlich gibt es Zeiten, in denen Sie das auch nicht wollen: Beurteilen Sie jeden Fall nach seinen Vorzügen. Es ist nur die "Ich weiß, dass diese Ressource mit dieser Klasse gebündelt ist" die häufigste, auf die ich gestoßen bin.
quelle
this.getClass()
. Erstellen Sie eine Instanz der Unterklasse und rufen Sie die Methode auf. Sie gibt den Namen der Unterklasse aus, nicht die Oberklasse.Ich suche drei Orte wie unten gezeigt. Kommentare willkommen.
quelle
Ich weiß, dass es für eine weitere Antwort sehr spät ist, aber ich wollte nur mitteilen, was mir am Ende geholfen hat. Es werden auch Ressourcen / Dateien aus dem absoluten Pfad des Dateisystems geladen (nicht nur aus dem Klassenpfad).
quelle
Ich habe viele Möglichkeiten und Funktionen ausprobiert, die oben vorgeschlagen wurden, aber sie haben in meinem Projekt nicht funktioniert. Jedenfalls habe ich eine Lösung gefunden und hier ist sie:
quelle
this.getClass().getResourceAsStream()
in diesem Fall besser verwenden . Wenn Sie sich die Quelle dergetResourceAsStream
Methode ansehen , werden Sie feststellen, dass sie dasselbe tut wie Sie, jedoch auf intelligentere Weise (Fallback, wennClassLoader
in der Klasse keine gefunden werden kann). Es zeigt auch , dass Sie ein Potential begegnen könnennull
aufgetClassLoader
im Code ...this.getClass().getResourceAsStream()
nicht für mich, also benutze ich das. Ich denke, es gibt einige Leute, die mit Problemen wie meinen konfrontiert werden können.