System.out.println () का उपयोग इतना बुरा क्यों है? [बन्द है]


18

बेशक, त्रुटि संदेशों या चेतावनियों के लिए लॉगिंग फ्रेमवर्क का उपयोग करना बहुत अच्छा है। लेकिन कभी-कभी मैं System.out.println () का उपयोग करता हूं, अगर मैं कम समय में कुछ नया करने की कोशिश करना चाहता हूं।

क्या कुछ त्वरित परीक्षण के लिए System.out.println () का उपयोग करना वास्तव में इतना बुरा है?


3
नहीं, यह एक त्वरित परीक्षा है, कौन परवाह करता है?
ब्रायन बोएचर

10
कौन कहता है कि यह बुरा है? विकल्प क्या है?
जेम्स

1
@Kayser स्थिर कोड समीक्षा टूल त्वरित परीक्षणों के लिए अनुपयुक्त हैं - वे कोड के लिए अधिक हैं जिन्हें आप दूसरों के साथ विकसित करना चाहते हैं (या दूसरों को समझना होगा)। मुझे लगता है कि इस वर्ष जो सबक सीखने को मिल रहा है, वह यह है कि कार्यदिवस के दौरान भी बहुत अलग समस्याएँ हैं, इसके लिए बहुत अलग टूलसेट और प्रथाओं की आवश्यकता होती है। तो अपने त्वरित परीक्षण के लिए, यह सब चक करें और ग्रूवी का उपयोग करें :)
बिल के

1
उपयोग करके System.err.println()देखें और देखें कि क्या होता है। मैं अनुमान लगा रहा हूं कि उपकरण सोचता है कि आप System.outगलत उद्देश्य के लिए उपयोग कर रहे हैं।
इज़काता

2
प्राथमिक समस्या स्केलेबिलिटी और नियंत्रण के साथ है। यदि आपके पास इनमें से लाखों कथन हैं, तो आप कैसे देख सकते हैं कि आपको क्या देखना है। यदि आपको इनमें से किसी एक पर प्रतिक्रिया करने की आवश्यकता है, तो आप उस प्रोग्राम को कैसे कर सकते हैं। लॉगिंग चौखटे आमतौर पर उन दो विचारों पर लागू होते हैं जो System.out पर लागू होते हैं।

जवाबों:


18

जैसा कि टिप्पणियों में पता चला है, असली सवाल पूछा जा रहा है, System.out.println के स्थिर कोड विश्लेषण उपकरण ध्वज का उपयोग क्यों करते हैं?

कारण यह है कि स्टडआउट को संदेश भेजना आमतौर पर उत्पादन के माहौल में अनुचित है। यदि आप किसी लाइब्रेरी को कोड कर रहे हैं, तो लाइब्रेरी को अपने कॉलर को जानकारी लौटा देनी चाहिए, प्रिंटआउट को प्रिंट नहीं करना चाहिए। यदि आप एक GUI ऐप को कोड कर रहे हैं, तो उपयोगकर्ता को जानकारी प्रस्तुत की जानी चाहिए, न कि जहां stdout होता है वह इंगित करने के लिए होता है (जो कहीं नहीं हो सकता है)। यदि आप किसी सर्वर (या सर्वर-साइड कंटेनर में चलने वाली किसी चीज़) को कोड कर रहे हैं, तो आपको जो भी लॉगिंग सुविधा प्रदान की गई है, उसका उपयोग करना चाहिए। इत्यादि।

लेकिन यदि आप डिबगिंग या विकास के लिए प्रिंटलाइन का उपयोग कर रहे हैं, या आप एक प्रोग्राम लिख रहे हैं और स्टड को पढ़ते हैं और स्टडआउट को लिखते हैं, तो प्रिंटलाइन पूरी तरह से ठीक है। उन मामलों के लिए इसके साथ कुछ भी गलत नहीं है।


3
अच्छा उत्तर। धन्यवाद .. +1 के लिए "यदि आप एक GUI ऐप को कोड कर रहे हैं, तो उपयोगकर्ता को जानकारी प्रस्तुत की जानी चाहिए, न कि जहाँ पर stdout होना इंगित करता है (जो कि कहीं नहीं हो सकता)"
Kayser

10

सभी stdoutबफर्ड हैं, और इस प्रकार यह संभव है कि आपका प्रोग्राम आपके बुलाए जाने के बाद क्रैश हो जाएगा println(), लेकिन इससे पहले कि वह स्क्रीन पर पहुंच जाए।

यह कहा जाने के साथ, यह परिदृश्य वास्तव में संभावना नहीं है। आगे बढ़ें और इसका उपयोग करें, लेकिन बस उस छोटी सी सीमा को अपने दिमाग के पीछे रखें।


कम से कम दो प्रमुख पायथन दुभाषिए बाहर निकलने से पहले सभी खुली फाइलों को फ्लश करने की बहुत कोशिश करते हैं, भले ही निकास एक अखंड अपवाद के कारण हो। क्या JVMs कुछ ऐसा ही नहीं करते हैं?

1
@delnan, संभवतः, लेकिन कुछ भी हो सकता है। (कोड जो फ्लड को फ्लश करता है, जहां समस्या सतही हो सकती है। आप जिस थ्रेड को चला रहे हैं, उसे बलपूर्वक बंद किया जा सकता है। वर्तमान प्रक्रिया को OS द्वारा मेमोरी से जबरदस्ती डंप किया जा सकता है।) मेरे बयान के आसपास अपना जीवन न जीएं, लेकिन बस इसके बारे में पता होना चाहिए।
riwalk

1
कोड जो फ्लश करता है वह VM में ही होता है और इस प्रकार भाषा में त्रुटियों से अप्रभावित होता है जो VM लागू करता है। जबरन प्रक्रिया समाप्त होने के बारे में अच्छी बात। लेकिन ध्यान दें कि उदाहरण के लिए यूनिक्स के SIGTERM और अधिकांश अन्य संकेतों को इस तरह से सफाई करने के लिए पकड़ा जा सकता है - हालांकि अधिक चरम SIGKILL के साथ काम नहीं करता है।

2
मुझे नहीं लगता कि मैंने कभी ऐसा देखा है या ऐसा होने के बारे में सुना है, हालांकि मैंने अन्य मुद्दों को देखा है। यह समस्या लॉगर जैसे टूल के साथ भी बेहतर होने की संभावना नहीं है क्योंकि वे अंतर्निहित टूल के रूप में System.out का उपयोग करने की संभावना रखते हैं।
बिल के

@delnan यह कभी नहीं मानती कि आपके क्लीनअप कोड को चलाने की गारंटी है ... और अंत में ब्लॉक में महत्वपूर्ण व्यापार लेनदेन कोड कभी नहीं डालें;) System.out डिबगिंग के लिए ठीक है, लेकिन बफरिंग के बारे में जागरूक रहें।
स्टीवन

8

System.outसिर्फ एक लपेटा हुआ है BufferedOutputStream। यह आपके द्वारा उपयोग किए जाने वाले किसी भी लॉगिंग ढांचे के समान है, फ्रेमवर्क आपके लॉग आउटपुट के कॉन्फ़िगरेशन और गंतव्य के रूप में अधिक कार्यक्षमता प्रदान करते हैं


4
यह वास्तव में सवाल का जवाब नहीं देता है। "क्या यह खराब है?"
सर्गगैस

@ बर्ग - क्योंकि प्रश्न का वह हिस्सा पूरी तरह से संदर्भ पर निर्भर है। (या बस, नहीं, यह बुरा नहीं है)
स्पिनिंग_प्लेट

7

यदि आप एक गैर-तुच्छ कार्यक्रम पर काम कर रहे हैं और यह बुरा है

  • स्वचालित इकाई परीक्षण (JUnit) के बजाय एक बैसाखी के रूप में System.out का उपयोग कर रहे हैं
  • System.out स्टेटमेंट को बनाने और हटाने या टिप्पणी करने / टिप्पणी करने में बहुत समय व्यतीत करें

1
अधिकांश IDE के पास ऑटोकॉम्पलेटिंग सिस्टम के लिए हॉटकीज़ होना चाहिए। एक पंक्ति को टिप्पणी / अनसुना करना, और एक लाइन हटाना। आप सिद्धांत रूप में सही हैं कि इसके अत्यधिक उपयोग से बचने की कोशिश करें, लेकिन आप कम से कम इस तरह से समय बचा सकते हैं।
स्टीवन

7

System.outफेंकने के कोड में भी, उपयोग करने के बारे में कुछ चेतावनी हैं ।

एक बड़ी समस्या यह है कि यह आमतौर पर धीमा है । उदाहरण के लिए, यदि आप कुछ कोड की गति के बारे में एक मोटा विचार प्राप्त करने की कोशिश कर रहे हैं (ध्यान दें कि माइक्रोबेनचर्क कठिन हैं ), तो System.out.println()कहीं भी एक जोड़ना वास्तव में आपके समय को गड़बड़ कर सकता है (क्योंकि यह सिंक्रनाइज़ कर रहा है और अक्सर वास्तविक आउटपुट की प्रतीक्षा करता है। लौटने से पहले उपयोगकर्ता को दिखाई दे)।

इसके अलावा, मैं इसके बारे में बहुत ज्यादा चिंता नहीं करूँगा कि यह कोड में है। यदि आप इसे करने का इरादा रखते हैं (इसे उत्पादन कोड के रूप में या परीक्षण कोड के रूप में), तो आपको इससे छुटकारा पाना चाहिए और इसे एक प्रॉपर लॉगिंग कॉल (हां, यहां तक कि परीक्षण कोड में) से बदलना चाहिए ।


प्रदर्शन एक अच्छा तर्क है ..
Kayser

4

जैसा कि अक्सर होता है, उत्तर "यह निर्भर करता है" है। यदि आपके आवेदन में पहले से ही एक लॉगिंग ढाँचा है, तो आप उसका उपयोग भी कर सकते हैं। यह कम सक्षम नहीं हो सकता है println(), और आप इसे प्रदान करने वाली अन्य सुविधाओं से लाभ उठा सकते हैं - स्टैक निशान, अतिरिक्त संदर्भ, बेहतर स्वरूपण, और इसी तरह। इस बात की भी अलग संभावना है कि लॉगिंग चौखटे बेहतर त्रुटि सुधार की पेशकश करते हैं, यह सुनिश्चित करता है कि आपके लॉग सफलतापूर्वक एक विपत्तिपूर्ण विफलता की स्थिति में भी लिखे गए हैं।

तो सवाल यह हो जाता है कि पहली बार लॉगिंग सिस्टम को कब जोड़ा जाए। यह एक निर्णय कॉल है: आप इसे बहुत जल्दी जोड़ना नहीं चाहते हैं, केवल यह पता लगाने के लिए कि आपको वास्तव में इसकी कोई आवश्यकता नहीं है। आप इसे बहुत देर से जोड़ना नहीं चाहते हैं, और अपने तदर्थ समाधान से अत्यधिक काम करना चाहते हैं।

यदि आपको पता चलता है कि आप बहुत से लॉगिंग कर रहे हैं println(), तो आपका कोडबेस आपको यह बताने की कोशिश कर रहा है कि यह बढ़ते दर्द का अनुभव कर रहा है। उस समय, यह उचित लॉगिंग में निवेश करने के लिए लायक है।


3

मुझे अक्सर यह समस्या होती है कि System.out.print "सिस्टम डिफॉल्ट" कोडपेज का उपयोग करता है, जो अक्सर लिनक्स के तहत UTF-8 होता है, लेकिन कुछ ने विंडोज के तहत एमएस सामान को तरसा दिया।

यह उन यूनिकोड वर्णों को जन्म दे सकता है जो प्रोग्राम के चलने के आधार पर स्क्रीन पर सही ढंग से मुद्रित नहीं हैं या नहीं हैं।

इसलिए मैं System.out पर एक कस्टम PrintWriter पसंद करता हूं


तृप्त होकर एमएस सामान। आपका मतलब CP1352 या UTF16 है?
कोल जॉनसन

@ColeJohnson: Windows कंसोल विंडो दुर्भाग्य से अभी भी पूर्व-UTF16 युग में अटकी हुई है। हालाँकि, अंतर्निहित कंसोल के साथ एक फलक IDE का उपयोग करके उस समस्या को कम किया जा सकता है।
जोकिम सॉउर

@Cole Johnson - मैं CP 65001 (यानी utf8) के साथ रह सकता था, लेकिन ऐसा लगता है कि इसे "सिस्टम डिफॉल्ट" कोडपेज के रूप में प्राप्त करने का कोई तरीका नहीं है, उदाहरण के लिए, आपके पास एक जर्मन कीबोर्ड है जो आपको CP 850 या कुछ ऐसे मिलते हैं।
इंगो

1

यह बुरा नहीं है। धारणा इस तथ्य से उपजी हो सकती है कि यह बहुत ही सरल है और आपके एप्लिकेशन में समर्पित लॉगिंग फ्रेमवर्क का उपयोग करते हुए परिष्कृत नहीं है।

हालांकि, यह कहना नहीं है कि यह एक अमान्य दृष्टिकोण है। मैं कुछ काले जादू जादू प्रोग्रामिंग hijinks के बाद आवेदन प्रवाह की जांच करने के लिए कई बार इसका इस्तेमाल किया है ।


0

इसका उपयोग करने में कुछ भी गलत नहीं है, यह आपको यह पता लगाने में मदद करता है कि 'क्या चल रहा है'।

लेकिन अगर आपके सहकर्मी / अन्य देव / उपकरण आपका उपहास कर रहे हैं, तो आप हमेशा लकड़हारा का उपयोग कर सकते हैं , या जूनिट परीक्षण शुरू कर सकते हैं !


0

ऑकेशनल सिस्टम.आउट.प्रिंट्लन के साथ सबसे बड़ा मुद्दा, जैसा कि मैं देख रहा हूं, यह है कि यह एक "बुरी आदत गंध (टीएम)" है। यदि आप अपने आप को ऐसा करते हुए पाते हैं, तो आप संभवतः अपने पसंदीदा डिबगर का उपयोग करके अधिक सहजता से अपनी प्रभावकारिता में सुधार कर सकते हैं।

डिबगर के साथ, आप कुछ के लिए जानते हैं कि एक ब्रेकपॉइंट आपके उत्पादन कोड में नहीं जाएगा, जबकि एक System.out.println हो सकता है।

एक साइड नोट पर, यदि आप वास्तव में सिर्फ एक त्वरित परीक्षा कर रहे हैं और डिबगर का उपयोग नहीं करने के साथ बने रहते हैं, तो मुझे लगता है कि System.out.println लॉगिंग फ्रेमवर्क का उपयोग करने से बेहतर है, क्योंकि यदि आप गलती से लॉग.डबग स्टेटमेंट छोड़ देते हैं तो 'फिर से किया, यह मुश्किल से जड़ है।


0

आंतरिक राज्य की सामग्री को प्रतिध्वनित करने के इर्द-गिर्द एक संपूर्ण परीक्षण रणनीति का निर्माण सबसे चतुर चाल नहीं है, लेकिन विकास में कोड के त्वरित और गंदे परीक्षणों के लिए यहां पर अजीब प्रिंटलाइन है और जब तक आप उन्हें हटाने के लिए याद नहीं करते तब तक चोट नहीं पहुंचेगी!

उन्हें हटाने के लिए भूलने का खतरा शायद इसीलिए इसके खिलाफ सलाह दी जाती है।


आपकी राय में उन्हें हटाने की भूल करने से क्या समस्या है? यकीन है कि कंसोल पर कुछ संदेश अधिक होंगे। क्या आपको कोई अन्य समस्या दिखाई देती है?
कायर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.