Saya memiliki kelas yang harus memiliki beberapa metode statis. Di dalam metode statis ini saya perlu memanggil metode getClass () untuk melakukan panggilan berikut:
public static void startMusic() {
URL songPath = getClass().getClassLoader().getResource("background.midi");
}
Namun Eclipse memberi tahu saya:
Cannot make a static reference to the non-static method getClass()
from the type Object
Apa cara yang tepat untuk memperbaiki kesalahan waktu kompilasi ini?
java
static-methods
Rama
sumber
sumber
getResource()
sebelum ada turunan dari kelas yang ditentukan pengguna (misalnya non-J2SE) terkadang akan gagal. Masalahnya adalah bahwa JRE akan menggunakan bootstrap class-loader pada tahap itu, yang tidak akan memiliki sumber daya aplikasi di jalur-kelas (dari bootstrap loader).Jawaban:
Jawabannya
Cukup gunakan
TheClassName.class
sajagetClass()
.Deklarasikan Penebang
Karena ini mendapat begitu banyak perhatian untuk penggunaan khusus - untuk memberikan cara mudah untuk memasukkan deklarasi log - saya pikir saya akan menambahkan pemikiran saya tentang itu. Kerangka kerja log sering mengharapkan log dibatasi pada konteks tertentu, misalnya nama kelas yang sepenuhnya memenuhi syarat. Jadi mereka tidak dapat disalin tanpa modifikasi. Saran untuk deklarasi log safe-paste disediakan dalam jawaban lain, tetapi mereka memiliki kelemahan seperti menggembungkan bytecode atau menambahkan introspeksi runtime. Saya tidak merekomendasikan ini. Copy-paste adalah masalah editor , jadi solusi editor yang paling tepat.
Di IntelliJ, saya sarankan menambahkan Template Langsung:
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class);
sebagai teks templat.className()
Sekarang jika Anda mengetiknya
log<tab>
akan secara otomatis diperluas keDan secara otomatis memformat ulang dan mengoptimalkan impor untuk Anda.
sumber
Log
di Android, yang membutuhkan tag yang harus disediakan, biasanya nama kelas. Dan mungkin ada contoh lain. Tentu saja Anda dapat mendeklarasikan bidang untuk itu (yang merupakan praktik umum), tetapi itu masih menyalin dan menempel.CLASS
mengetikclassName()
. Itu akan memastikan bahwa $ CLASS $ benar-benar diganti dengan nama kelas, kalau tidak hanya akan keluar kosong.Adapun contoh kode dalam pertanyaan, solusi standar adalah merujuk kelas secara eksplisit dengan namanya, dan bahkan mungkin dilakukan tanpa
getClassLoader()
panggilan:Pendekatan ini masih memiliki sisi belakang yang tidak terlalu aman terhadap kesalahan salin / rekat jika Anda perlu mereplikasi kode ini ke sejumlah kelas serupa.
Dan untuk pertanyaan yang tepat dalam informasi utama, ada trik yang diposting di utas yang berdekatan :
Ini menggunakan anonim bersarang
Object
subclass untuk mendapatkan konteks eksekusi. Trik ini bermanfaat untuk menjadi salin / tempel aman ...Perhatian saat menggunakan ini di Kelas Dasar yang berasal dari kelas lain:
Perlu juga dicatat bahwa jika potongan ini dibentuk sebagai metode statis dari beberapa kelas dasar maka
currentClass
nilai akan selalu menjadi referensi ke kelas dasar itu daripada ke subkelas yang mungkin menggunakan metode itu.sumber
Class.getResource()
mungkin berperilaku sedikit berbeda dariClassLoader.getResource()
; lihat stackoverflow.com/a/676273Di Java7 + Anda dapat melakukan ini dalam metode / bidang statis:
sumber
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
Saya sendiri bergulat dengan ini. Trik yang bagus adalah menggunakan gunakan utas saat ini untuk mendapatkan ClassLoader ketika dalam konteks statis. Ini akan bekerja di Hadoop MapReduce juga. Metode lain berfungsi saat berjalan secara lokal, tetapi mengembalikan InputStream nol saat digunakan di MapReduce.
sumber
Cukup gunakan literal kelas, yaitu
NameOfClass.class
sumber
getClass()
Metode didefinisikan dalam kelas Obyek dengan tanda tangan berikut:Karena tidak didefinisikan sebagai
static
, Anda tidak dapat menyebutnya dalam blok kode statis. Lihat jawaban ini untuk informasi lebih lanjut: Q1 , Q2 , Q3 .Jika Anda berada dalam konteks statis, maka Anda harus menggunakan ekspresi literal kelas untuk mendapatkan Kelas, jadi pada dasarnya Anda harus melakukan seperti:
Jenis ekspresi ini disebut Literals Kelas dan dijelaskan dalam Buku Spesifikasi Bahasa Jawa sebagai berikut:
Anda juga dapat menemukan informasi tentang subjek ini pada dokumentasi API untuk Kelas.
sumber
Cobalah
Atau
sumber
[1]
akan menyebabkan semua pesan log dilaporkanThread
sebagai sumbernya di Android 4.4.4.[2]
tampaknya memberikan hasil yang benar pada Android dan OpenJRE.Misalkan ada kelas Utilitas, maka kode sampel akan menjadi -
CustomLocation - jika ada struktur folder dalam sumber daya yang lain hilangkan string literal ini.
sumber
Coba sesuatu seperti ini. Ini bekerja untuk saya. Logg (Nama kelas)
sumber