हम लॉगर्स को स्थिर फाइनल क्यों घोषित करते हैं?


131

जावा में, लकड़हारा घोषित करना सबसे अच्छा अभ्यास क्यों है static final?

private static final Logger S_LOGGER

जवाबों:


209
  • private- तो कोई अन्य वर्ग सकता है कि अपहरण अपने लकड़हारा
  • static - इसलिए प्रति वर्ग केवल एक लकड़हारा उदाहरण है, जो लकड़हारे को अनुक्रमित करने के प्रयासों से भी बचता है
  • final - कक्षा के जीवनकाल में लकड़हारे को बदलने की कोई आवश्यकता नहीं है

इसके अलावा, मैं नाम logको यथासंभव सरल होना चाहता हूं , फिर भी वर्णनात्मक।

EDIT: हालाँकि इन नियमों का एक दिलचस्प अपवाद है:

protected final Logger log = LoggerFactory.getLogger(getClass());

विरोध के रूप में:

private static final Logger log = LoggerFactory.getLogger(Foo.class);

पूर्व तरीका आपको वंशानुक्रम पदानुक्रम में सभी वर्गों में एक ही लकड़हारा नाम (वास्तविक वर्ग का नाम) का उपयोग करने की अनुमति देता है। इसलिए अगर Barविस्तार होता है Foo, तो दोनों Barलकड़हारे को लॉग इन करेंगे । कुछ को यह अधिक सहज लगता है।


36
अगर स्थैतिक और अंतिम है तो लॉग (अपरकेस)
zacheusz

39
@zacheusz , मुझे पता है, यह बात है। कुछ लोग धार्मिक रूप से जावा नामकरण सम्मेलन का पालन करते हैं (इसके साथ कुछ भी गलत नहीं है), लेकिन मुझे लिखना आसान लगता है और logकोड को बिखरने के बजाय नाम पढ़ने में अधिक सुखद लगता है LOG। बस देव की बात है। टीम का समझौता।
टॉमाज़ नर्कविक्ज़

27
कृपया ध्यान दें कि लॉगर को स्थिर और अंतिम घोषित करने के लिए हमेशा अनुशंसा नहीं की जाती है, slf4j.org/faq.html#declared_static और wiki.apache.org/commons/Logging/Frequently.skedQuestions खंड देखें, मुझे लॉग संदर्भों को स्थिर घोषित करना चाहिए या नहीं?
मैथ्यू फरवेल

6
@zacheusz बड़े क्षेत्र का नाम स्थिरांक के लिए उपयोग किया जाता है। लकड़हारा स्थिर नहीं है। http://stackoverflow.com/questions/1417190/should-a-static-final-logger-be-declared-in-upper-case
michal.kreuzman

2
@zacheusz सभी स्थिर अंतिम विशेषताएँ UPPERCASE नहीं होनी चाहिए: stackoverflow.com/questions/1417190/…
bsmk

15

इस ब्लॉग पोस्ट की जाँच करें: जावा स्टेटिक लॉगर्स से छुटकारा पाएं । इस तरह से आप jcabi-log के साथ slf4j का उपयोग करते हैं :

import com.jcabi.log.Logger;
class Foo {
  void save(File f) {
    Logger.info(this, "file %s saved successfully", f);
  }
}

और कभी भी उस स्थिर शोर का उपयोग न करें।


एक दिलचस्प विकल्प और निश्चित रूप से क्लीनर। मुझे आश्चर्य है कि व्यक्तिगत वर्ग के लकड़हारे की तुलना में यह तराजू कैसे है।
रोस

12
हर बार लंबे लकड़हारे को लिखें .. (यह, ...)। नाह।
मिखाइल बोयार्स्की 15

संबंधित ब्लॉग पोस्ट में पहली टिप्पणी स्थिर तरीकों के बुरे पक्ष को इंगित करती है :) इसलिए निजी अंतिम लकड़हारा का उपयोग करना सबसे अच्छा अभ्यास है जो मुझे लगता है।
बहदिर तसदीम

5

staticका मतलब है कि आप केवल प्रति एक लकड़हारा वर्ग प्रति एक लॉगर बनाने के लिए, नहीं उदाहरण के अपने वर्ग के। आमतौर पर, यह वही है जो आप चाहते हैं - क्योंकि लकड़हारे पूरी तरह से वर्ग के आधार पर भिन्न होते हैं।

finalइसका मतलब है कि आप loggerवैरिएबल के मूल्य को बदलने नहीं जा रहे हैं । यह सच है, क्योंकि आप लगभग सभी लॉग संदेश (एक वर्ग से) एक ही लकड़हारे को फेंक देते हैं। यहां तक ​​कि उन दुर्लभ मौकों पर भी जहां एक वर्ग किसी भिन्न लकड़हारे को कुछ संदेश भेजना चाहता है, यह widgetDetailLoggerमक्खी पर स्थैतिक चर के मूल्य को बदलने के बजाय एक और लकड़हारा चर (जैसे ) बनाने के लिए बहुत स्पष्ट होगा ।


4

आप फ़ील्ड का मान कब बदलना चाहेंगे?

यदि आप कभी भी मूल्य को बदलने नहीं जा रहे हैं, तो फ़ील्ड फाइनल करना यह स्पष्ट करता है कि आप कभी भी मूल्य नहीं बदलेंगे।


1
कई-कई मामलों में, यह अंतिम शब्द जोड़े बिना स्पष्ट है, जो कि यह मामला एक प्रकार का कबाड़ बन जाता है।
दीमा

2
@ डिमा: मैं अभी भी आभारी हूं कि कंपाइलर अभी भी एक त्रुटि करेगा, अगर मैं गलती से इन मामलों में मूल्य को बदलने की कोशिश करूं ...
जॉन स्कीट

3

आम तौर पर आप लकड़हारे को वर्ग नाम का उपयोग करने के लिए लॉग इन करते हैं - जिसका अर्थ है कि यदि वे स्थिर नहीं थे, तो आप कक्षा के प्रत्येक उदाहरण के साथ इसका एक उदाहरण (उच्च स्मृति पदचिह्न) रखते हुए समाप्त हो जाएंगे, लेकिन ये सभी लकड़हारे समान कॉन्फ़िगरेशन साझा करें और बिल्कुल वैसा ही व्यवहार करें। यही कारण है कि staticबिट के पीछे । इसके अलावा, क्योंकि प्रत्येक Loggerको वर्ग नाम के साथ आरम्भ किया गया है, उपवर्गों के साथ संघर्ष को रोकने के लिए, आप इसे घोषित करते हैं privateताकि यह विरासत में न मिले। finalबिंदु से आता है कि आप सामान्य रूप से परिवर्तन नहीं करते Loggerनिष्पादन के दौरान - (इस स्थिति में यह समझ में आता है यह सुनिश्चित करने के लिए कोई भी इसे बदल सकते हैं अंतिम बनाने के लिए द्वारा - तो एक बार आप कभी नहीं "फिर से कॉन्फ़िगर किया गया" प्रारंभ यह गलती या अन्यथा)। बेशक अगर आप एक का उपयोग करने जा रहे हैंLoggerएक अलग तरीके से आपको उपयोग करने की आवश्यकता नहीं हो सकती है static final- लेकिन मैं अनुमान लगाऊंगा कि 80% एप्स ऊपर बताए अनुसार लॉगिंग का उपयोग करेंगे।


3

उस प्रश्न का उत्तर देने के लिए, आपको अपने आप से पूछना चाहिए कि "स्थिर" और "अंतिम" क्या हैं।

एक लकड़हारा के लिए, (मुझे लगता है कि आप Log4J लकड़हारा वर्ग के बारे में बात करते हैं) आप प्रति वर्ग एक श्रेणी चाहते हैं। इस तथ्य को जन्म देना चाहिए कि आप इसे केवल एक बार असाइन करते हैं, और प्रति वर्ग एक से अधिक उदाहरणों की आवश्यकता नहीं है। और संभवतः एक कक्षा से दूसरे वर्ग के लकड़हारे वस्तु को उजागर करने का कोई कारण नहीं है, इसलिए न ही इसे निजी बनाएं और कुछ ऊ-सिद्धांतों का पालन करें।

इसके अलावा, आपको ध्यान देना चाहिए कि संकलक उस का लाभ उठाने में सक्षम है। तो आपका कोड थोड़ा बेहतर प्रदर्शन करता है :)


2

क्योंकि यह आमतौर पर एक प्रकार का कार्य है जिसे आपकी वस्तुओं के सभी उदाहरणों के साथ साझा किया जा सकता है। एक ही वर्ग के दो उदाहरणों के लिए एक अलग लकड़हारा होना बहुत मायने नहीं रखता (90% समय)।

हालाँकि, आप कभी-कभी लॉगर वर्गों को एकल के रूप में घोषित या यहां तक ​​कि अपने सामान को लॉग करने के लिए स्थिर कार्यों की पेशकश भी देख सकते हैं।


2

यह कोड असुरक्षित , है, लेकिन Java7 के बाद, हम Logger lgr = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); स्टैटिक लॉगर के बजाय उपयोग कर सकते हैं ।


This is code is vulnerableक्या आप स्पष्ट कर सकते हैं कि आप थोड़ा जवाब दें?
दिमित्री ज़गोरुलकिन

1

ज्यादातर मामलों में, आप संदर्भ को बदलने नहीं जा रहे हैं और finalसंशोधक इसे चिह्नित करता है। आपको प्रत्येक श्रेणी उदाहरण के लिए अलग-अलग उदाहरणों की आवश्यकता नहीं है - इसलिए static। और सबसे पहले यह प्रदर्शन के लिए है - यह अच्छी तरह से अनुकूलित (अंतिम) हो सकता है और मेमोरी (स्थिर) बचाता है।


1

आदर्श रूप से लकड़हारा जावा 7 तक का होना चाहिए, बिना सोनार देने और एक शिकायत कोड देने के लिए: निजी: अपने मूल वर्ग के बाहर कभी भी सुलभ नहीं होना चाहिए। यदि किसी अन्य वर्ग को कुछ लॉग करने की आवश्यकता है, तो उसे अपने स्वयं के लकड़हारे को तुरंत भेज देना चाहिए। स्थैतिक: एक वर्ग (एक वस्तु) की आवृत्ति पर निर्भर नहीं होना चाहिए। कुछ लॉग करते समय, प्रासंगिक जानकारी संदेशों में प्रदान की जा सकती है, लेकिन प्रत्येक वस्तु के साथ एक लकड़हारा बनाने के लिए और इसलिए हाई मेमोरी फ़ुटप्रिंट को रोकने के लिए लकड़हारा को कक्षा स्तर पर बनाया जाना चाहिए। अंतिम: प्रति कक्षा एक बार और केवल एक बार बनाया जाए।


0

अन्य उत्तरों में दिए गए कारणों के अलावा, एक बात जो मुझे भा गई, वह यह कि अगर मेरा लकड़हारा न तो स्थिर था और न ही अंतिम:

...
public Logger logger = LoggerFactory.getLogger(DataSummary.class);

public String toJson() {
  GsonBuilder gsonBuilder = new GsonBuilder();   
  return gsonBuilder.create().toJsonTree(this).toString();
}
...

कुछ मामलों में (जब मैं गन्स लाइब्रेरी का उपयोग कर रहा था) तो मुझे स्टैकओवरफ्लो अपवाद मिलेगा। मेरी विशिष्ट स्थिति गैर-स्थिर गैर अंतिम लकड़हारे वाले वर्ग को त्वरित करने की थी। फिर जेजसन विधि को कॉल करें जिसने GsonBuilder को आमंत्रित किया:

...
DataSummary ds = new DataSummary(data);    
System.out.println(ds.toJson());
...

0

वास्तव में स्टैटिक लॉगर "हानिकारक" हो सकते हैं क्योंकि वे एक स्थिर संदर्भ में काम करने वाले होते हैं। जब एक गतिशील वातावरण उदा। OSGi यह गैर-स्थिर लॉगर का उपयोग करने में मदद कर सकता है। जैसा कि कुछ लॉगिंग कार्यान्वयन आंतरिक रूप से लॉगर्स का एक कैशिंग करते हैं (AFAIK कम से कम log4j) प्रदर्शन प्रभाव नगण्य हो सकता है।

स्टेटिक लॉगर्स की एक खामी है। कचरा संग्रह (जब एक वर्ग केवल एक बार उपयोग किया जाता है जैसे। प्रारंभ के दौरान लकड़हारा अभी भी चारों ओर रखा जाएगा)।

अधिक जानकारी के लिए जाँच करें:

यह सभी देखें:


0

जानकारी के अनुसार मैं लकड़हारे को स्थिर बनाने या न बनाने के बारे में इंटरनेट से पढ़ता हूं, सबसे अच्छा अभ्यास उपयोग मामलों के अनुसार इसका उपयोग करना है।

दो मुख्य तर्क हैं:

1) जब आप इसे स्थिर बनाते हैं, तो यह कचरा एकत्र नहीं किया जाता है (मेमोरी उपयोग और प्रदर्शन)।

2) जब आप इसे स्थिर नहीं बनाते हैं तो यह प्रत्येक वर्ग उदाहरण (मेमोरी उपयोग) के लिए बनाया जाता है

इस प्रकार, जब आप एक सिंगलटन के लिए एक लकड़हारा बना रहे हैं, तो आपको इसे स्थिर बनाने की आवश्यकता नहीं है। क्योंकि इस प्रकार केवल एक उदाहरण होगा एक लकड़हारा।

दूसरी ओर, यदि आप किसी मॉडल या एंटिटी क्लास के लिए लकड़हारा पैदा कर रहे हैं, तो आपको यह सुनिश्चित करना चाहिए कि डुप्लिकेट लॉगर न बनाएं।


-1

आपको अभी भी आंतरिक स्थिर वर्गों के लिए स्थिर लकड़हारा चाहिए

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.