Saya ingin tahu cara terbaik memuat sumber daya di Java:
this.getClass().getResource() (or getResourceAsStream())
,Thread.currentThread().getContextClassLoader().getResource(name)
,System.class.getResource(name)
.
Cari solusinya sesuai dengan yang Anda inginkan ...
Ada dua hal yang akan getResource
/ getResourceAsStream()
dapatkan dari kelas tempat dipanggilnya ...
Jadi jika Anda melakukannya
this.getClass().getResource("foo.txt");
ini akan mencoba memuat foo.txt dari paket yang sama dengan kelas "this" dan dengan pemuat kelas dari kelas "this". Jika Anda meletakkan "/" di depan maka Anda benar-benar mereferensikan sumber daya.
this.getClass().getResource("/x/y/z/foo.txt")
akan memuat sumber daya dari pemuat kelas "this" dan dari paket xyz (ini harus berada di direktori yang sama dengan kelas dalam paket itu).
Thread.currentThread().getContextClassLoader().getResource(name)
akan memuat dengan pemuat kelas konteks tetapi tidak akan menyelesaikan nama sesuai dengan paket apa pun (itu harus benar-benar direferensikan)
System.class.getResource(name)
Akan memuat sumber daya dengan pemuat kelas sistem (itu harus benar-benar direferensikan juga, karena Anda tidak akan dapat memasukkan apa pun ke dalam paket java.lang (paket Sistem).
Lihat saja sumbernya. Juga menunjukkan bahwa getResourceAsStream hanya memanggil "openStream" pada URL yang ditampilkan dari getResource dan menampilkannya.
Thread#setContextClassLoader
. Ini berguna jika Anda perlu mengubah jalur kelas saat program sedang dijalankan.Yah, itu sebagian tergantung pada apa yang Anda inginkan terjadi jika Anda benar - benar berada di kelas turunan.
Misalnya, anggap
SuperClass
dalam A.jar danSubClass
dalam B.jar, dan Anda menjalankan kode dalam metode instance yang dideklarasikanSuperClass
tetapi di manathis
merujuk ke instanceSubClass
. Jika Anda menggunakannyathis.getClass().getResource()
akan terlihat relatifSubClass
, di B.jar. Saya rasa biasanya bukan itu yang diminta.Secara pribadi saya mungkin
Foo.class.getResourceAsStream(name)
paling sering menggunakan - jika Anda sudah tahu nama sumber daya yang Anda cari, dan Anda yakin di mana itu relatifFoo
, itulah cara paling kuat untuk melakukannya IMO.Tentu saja ada kalanya Anda juga tidak menginginkannya: menilai setiap kasus berdasarkan manfaatnya. Hanya "Saya tahu sumber daya ini digabungkan dengan kelas ini" adalah yang paling umum yang pernah saya temui.
sumber
this.getClass()
. Buat sebuah instance dari subclass dan panggil metode ... itu akan mencetak nama subclass tersebut, bukan superclassnya.Saya mencari tiga tempat seperti yang ditunjukkan di bawah ini. Komentar diterima.
sumber
Saya tahu ini sangat terlambat untuk jawaban lain tetapi saya hanya ingin berbagi apa yang membantu saya pada akhirnya. Ini juga akan memuat resource / file dari jalur absolut sistem file (tidak hanya classpath).
sumber
Saya mencoba banyak cara dan fungsi yang disarankan di atas, tetapi tidak berhasil dalam proyek saya. Pokoknya saya sudah menemukan solusinya dan ini dia:
sumber
this.getClass().getResourceAsStream()
dalam kasus ini. Jika Anda melihat sumbergetResourceAsStream
metode, Anda akan melihat bahwa ia melakukan hal yang sama dari Anda tetapi dengan cara yang lebih cerdas (fallback jika tidak ada yangClassLoader
dapat ditemukan di kelas). Ini juga menunjukkan bahwa Anda dapat menemukan potensinull
digetClassLoader
dalam kode Anda…this.getClass().getResourceAsStream()
tidak berfungsi untuk saya, jadi saya menggunakan yang berfungsi. Saya pikir ada beberapa orang yang bisa menghadapi masalah seperti saya.