Di Jawa, mengapa praktik terbaik untuk mendeklarasikan logger static final
?
private static final Logger S_LOGGER
Di Jawa, mengapa praktik terbaik untuk mendeklarasikan logger static final
?
private static final Logger S_LOGGER
Jawaban:
private
- sehingga tidak ada kelas lain yang dapat membajak logger Andastatic
- jadi hanya ada satu instance logger per kelas, juga menghindari upaya untuk membuat serial loggerfinal
- tidak perlu mengubah logger selama masa pakai kelasJuga, saya lebih suka nama log
sesederhana mungkin, namun deskriptif.
EDIT: Namun ada pengecualian yang menarik untuk aturan ini:
protected final Logger log = LoggerFactory.getLogger(getClass());
sebagai lawan:
private static final Logger log = LoggerFactory.getLogger(Foo.class);
Cara sebelumnya memungkinkan Anda untuk menggunakan nama logger yang sama (nama kelas aktual) di semua kelas di seluruh hierarki warisan. Jadi jika Bar
diperluas Foo
, keduanya akan masuk ke Bar
logger. Beberapa merasa lebih intuitif.
log
nama daripada menyebarkan kode dengan LOG
. Hanya masalah dev. perjanjian tim.
Periksa posting blog ini: Singkirkan Java Static Loggers . Ini adalah bagaimana Anda menggunakan slf4j dengan jcabi-log :
import com.jcabi.log.Logger;
class Foo {
void save(File f) {
Logger.info(this, "file %s saved successfully", f);
}
}
Dan jangan pernah menggunakan kebisingan statis itu lagi.
static
berarti Anda hanya membuat satu Logger per kelas, bukan satu logger per instance kelas Anda. Secara umum, inilah yang Anda inginkan - karena para penebang cenderung bervariasi hanya berdasarkan kelas.
final
berarti Anda tidak akan mengubah nilai logger
variabel. Yang benar, karena Anda hampir selalu membuang semua pesan log (dari satu kelas) ke logger yang sama. Bahkan pada kesempatan langka di mana kelas mungkin ingin mengirim beberapa pesan ke logger yang berbeda, akan jauh lebih jelas untuk membuat variabel logger lain (misalnya widgetDetailLogger
) daripada dengan memutasikan nilai variabel statis dengan cepat.
Kapan Anda ingin mengubah nilai bidang?
Jika Anda tidak akan pernah mengubah nilainya, membuat final bidang membuatnya jelas bahwa Anda tidak akan pernah mengubah nilainya.
Biasanya Anda menginisialisasi logger untuk login menggunakan nama kelas - yang berarti bahwa jika mereka tidak statis, Anda akan berakhir dengan setiap instance dari kelas yang memiliki instance dari itu (jejak memori tinggi), tetapi semua penebang ini akan berbagi konfigurasi yang sama dan berperilaku sama persis. Itulah alasan di balik itu static
. Juga karena masing Logger
- masing diinisialisasi dengan nama kelas, untuk mencegah konflik dengan subclass, Anda mendeklarasikannya private
sehingga tidak dapat diwarisi. Itu final
datang dari titik yang biasanya Anda tidak mengubah Logger
selama eksekusi - jadi setelah diinisialisasi Anda tidak pernah "mengkonfigurasi ulang" itu - dalam hal ini masuk akal untuk membuatnya final untuk memastikan tidak ada yang bisa mengubahnya (oleh kesalahan atau sebaliknya). Tentu saja jika Anda akan menggunakanLogger
dengan cara yang berbeda, Anda mungkin TIDAK perlu menggunakan static final
- tapi saya berani menebak 80% aplikasi akan menggunakan logging seperti dijelaskan di atas.
Untuk menjawab pertanyaan itu, Anda seharusnya bertanya pada diri sendiri untuk apa "statis" dan "final".
Untuk seorang Logger, (saya berasumsi Anda berbicara tentang kelas Log4J Logger) Anda ingin kategori per kelas. Yang seharusnya mengarah pada fakta bahwa Anda menetapkannya hanya sekali, dan tidak perlu lebih dari satu instance per kelas. Dan mungkin tidak ada alasan untuk mengekspos objek Logger dari satu kelas ke kelas lain, jadi mengapa tidak menjadikannya pribadi dan mengikuti beberapa Prinsip-OO.
Anda juga harus mencatat, bahwa kompiler dapat mengambil manfaat dari itu. Jadi kode Anda berkinerja lebih baik :)
Karena itu biasanya jenis fungsi yang dapat dibagi di semua contoh objek Anda. Tidak masuk akal (90% dari waktu) memiliki logger berbeda untuk dua instance dari kelas yang sama.
Namun, Anda juga dapat melihat kadang-kadang kelas logger dinyatakan sebagai lajang atau bahkan hanya menawarkan fungsi statis untuk mencatat barang-barang Anda.
Kode ini rentan, tetapi, setelah Java7, kita dapat menggunakan Logger lgr = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
sebagai ganti dari pencatat statis.
This is code is vulnerable
Bisakah Anda menjelaskan sedikit jawaban?
Idealnya Logger harus sebagai tindak lanjut hingga Java 7, karena tidak memberikan Sonar dan memberikan Kode yang Memenuhi Syarat: pribadi: tidak pernah dapat diakses di luar kelas induknya. Jika kelas lain perlu mencatat sesuatu, itu harus membuat instance logger sendiri. statis: tidak bergantung pada turunan suatu kelas (objek). Saat mencatat sesuatu, informasi kontekstual tentu saja dapat disediakan dalam pesan tetapi logger harus dibuat di tingkat kelas untuk mencegah membuat logger bersama dengan setiap objek dan karenanya mencegah jejak Memori Tinggi. final: dibuat sekali dan hanya sekali per kelas.
Selain alasan yang diberikan dalam jawaban lain satu hal yang saya temui adalah bahwa jika logger saya tidak statis atau final:
...
public Logger logger = LoggerFactory.getLogger(DataSummary.class);
public String toJson() {
GsonBuilder gsonBuilder = new GsonBuilder();
return gsonBuilder.create().toJsonTree(this).toString();
}
...
dalam kasus-kasus tertentu (ketika saya menggunakan perpustakaan Gson) saya akan mendapatkan pengecualian stackoverflow. Situasi spesifik saya adalah untuk instantiate kelas yang berisi logger non final non statis. Kemudian panggil metode toJson yang memanggil GsonBuilder:
...
DataSummary ds = new DataSummary(data);
System.out.println(ds.toJson());
...
Sebenarnya penebang statis bisa "berbahaya" karena mereka seharusnya bekerja dalam konteks statis. Ketika memiliki lingkungan yang dinamis misalnya. OSGi mungkin membantu menggunakan penebang non-statis. Karena beberapa implementasi logging melakukan caching terhadap penebang secara internal (AFAIK setidaknya log4j) dampak kinerja mungkin dapat diabaikan.
Salah satu kelemahan dari penebang statis adalah misalnya. pengumpulan sampah (ketika sebuah kelas hanya digunakan sekali mis. selama inisialisasi logger akan tetap disimpan).
Untuk lebih jelasnya periksa:
Lihat juga:
Menurut info yang saya baca dari internet tentang membuat logger statis atau tidak, praktik terbaik adalah menggunakannya sesuai dengan kasus penggunaan.
Ada dua argumen utama:
1) Ketika Anda membuatnya statis, itu bukan sampah yang dikumpulkan (penggunaan memori & kinerja).
2) Ketika Anda tidak membuatnya statis itu dibuat untuk setiap instance kelas (penggunaan memori)
Jadi, Saat Anda membuat logger untuk singleton, Anda tidak perlu membuatnya statis. Karena hanya akan ada satu instance sehingga satu logger.
Di sisi lain, jika Anda membuat logger untuk kelas model atau entitas, Anda harus membuatnya statis untuk tidak membuat duplikat logger.