एंड्रॉइड ओपन सोर्स प्रोजेक्ट (एओएसपी) में जावा कोड का योगदान करने के लिए इस पृष्ठ पर कोड शैलियों सख्त नियम हैं। Android प्लेटफ़ॉर्म में योगदान जो इन नियमों का पालन नहीं करते हैं, उन्हें आमतौर पर स्वीकार नहीं किया जाता है । हम मानते हैं कि सभी मौजूदा कोड इन नियमों का पालन नहीं करते हैं, लेकिन हम सभी नए कोड के अनुपालन की उम्मीद करते हैं। अधिक समावेशी पारिस्थितिकी तंत्र के उपयोग और बचने के लिए शब्दावली के उदाहरणों के संबंध में कोडिंग देखें।
स्तिर रहो
सबसे सरल नियमों में से एक है निरंतर बने रहना। यदि आप कोड संपादित कर रहे हैं, तो आस-पास के कोड को देखने के लिए कुछ मिनट लें और उसकी शैली निर्धारित करें। यदि वह कोड if
क्लॉज के आसपास रिक्त स्थान का उपयोग करता है, तो आपको भी करना चाहिए। अगर कोड टिप्पणियों में सितारों के छोटे बक्से हैं, तो अपनी टिप्पणियों में उनके चारों ओर सितारों के छोटे बक्से भी हैं।
शैली दिशा-निर्देशों के होने की बात यह है कि कोडिंग की एक सामान्य शब्दावली हो, ताकि पाठक इस बात पर ध्यान केंद्रित कर सकें कि आप क्या कह रहे हैं, बजाय इसके कि आप इसे कैसे कह रहे हैं। हम यहां वैश्विक शैली के नियम प्रस्तुत करते हैं ताकि आप शब्दावली जान सकें, लेकिन स्थानीय शैली भी महत्वपूर्ण है। यदि आप किसी फ़ाइल में जो कोड जोड़ते हैं, वह उसके आस-पास के मौजूदा कोड से बहुत अलग दिखता है, तो जब पाठक इसे पढ़ते हैं तो यह लय से बाहर हो जाता है। इससे बचने का प्रयास करें।
जावा भाषा नियम
एंड्रॉइड नीचे वर्णित अतिरिक्त नियमों के साथ मानक जावा कोडिंग सम्मेलनों का पालन करता है।
अपवादों की उपेक्षा न करें
अपवाद को अनदेखा करने वाले कोड को लिखना आकर्षक हो सकता है, जैसे:
void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { } }
ऐसा मत करो। जबकि आप सोच सकते हैं कि आपका कोड कभी भी इस त्रुटि स्थिति का सामना नहीं करेगा या इसे संभालना महत्वपूर्ण नहीं है, इस प्रकार के अपवाद को अनदेखा करने से किसी और के लिए किसी दिन ट्रिगर करने के लिए आपके कोड में खदानें बन जाती हैं। आपको अपने कोड में प्रत्येक अपवाद को सैद्धांतिक तरीके से संभालना चाहिए; विशिष्ट हैंडलिंग मामले के आधार पर भिन्न होती है।
" कभी भी किसी के पास एक खाली कैच क्लॉज होता है तो उन्हें एक खौफनाक एहसास होना चाहिए। निश्चित रूप से ऐसा समय होता है जब यह वास्तव में सही काम होता है, लेकिन कम से कम आपको इसके बारे में सोचना होगा। जावा में आप खौफनाक एहसास से बच नहीं सकते। "- जेम्स गोस्लिंग
स्वीकार्य विकल्प (वरीयता के क्रम में) हैं:
- अपवाद को अपनी विधि के कॉलर तक फेंक दें।
void setServerPort(String value) throws NumberFormatException { serverPort = Integer.parseInt(value); }
- एक नया अपवाद फेंकें जो आपके अमूर्त स्तर के लिए उपयुक्त हो।
void setServerPort(String value) throws ConfigurationException { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { throw new ConfigurationException("Port " + value + " is not valid."); } }
- त्रुटि को शालीनता से संभालें और
catch {}
ब्लॉक में एक उपयुक्त मान रखें।/** Set port. If value is not a valid number, 80 is substituted. */ void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { serverPort = 80; // default port for server } }
- अपवाद को पकड़ें और
RuntimeException
का एक नया उदाहरण फेंकें। यह खतरनाक है, इसलिए इसे तभी करें जब आप सकारात्मक हों कि यदि यह त्रुटि होती है, तो उचित कार्य दुर्घटना है।/** Set port. If value is not a valid number, die. */ void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { throw new RuntimeException("port " + value " is invalid, ", e); } }
- अंतिम उपाय के रूप में, यदि आपको विश्वास है कि अपवाद को अनदेखा करना उचित है तो आप इसे अनदेखा कर सकते हैं, लेकिन आपको एक अच्छे कारण के साथ क्यों टिप्पणी करनी चाहिए।
/** If value is not a valid number, original port number is used. */ void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { // Method is documented to just ignore invalid user input. // serverPort will just be unchanged. } }
सामान्य अपवादों को न पकड़ें
अपवादों को पकड़ते समय आलसी होना आकर्षक हो सकता है और ऐसा कुछ करें:
try { someComplicatedIOFunction(); // may throw IOException someComplicatedParsingFunction(); // may throw ParsingException someComplicatedSecurityFunction(); // may throw SecurityException // phew, made it all the way } catch (Exception e) { // I'll just catch all exceptions handleError(); // with one generic handler! }
ऐसा मत करो। लगभग सभी मामलों में, सामान्य Exception
या Throwable
को पकड़ना अनुचित है (अधिमानतः Throwable
नहीं क्योंकि इसमें Error
अपवाद शामिल हैं)। यह खतरनाक है क्योंकि इसका मतलब है कि जिन अपवादों की आपने कभी उम्मीद नहीं की थी (रनटाइम अपवादों जैसे ClassCastException
सहित) ऐप-लेवल एरर हैंडलिंग में फंस जाते हैं। यह आपके कोड के विफलता-प्रबंधन गुणों को अस्पष्ट करता है, जिसका अर्थ है कि यदि कोई आपके द्वारा कॉल किए जा रहे कोड में एक नए प्रकार का अपवाद जोड़ता है, तो संकलक यह इंगित नहीं करेगा कि आपको त्रुटि को अलग तरीके से संभालने की आवश्यकता है। ज्यादातर मामलों में आपको विभिन्न प्रकार के अपवादों को एक ही तरह से नहीं संभालना चाहिए।
इस नियम का दुर्लभ अपवाद परीक्षण कोड और शीर्ष-स्तरीय कोड है जहां आप सभी प्रकार की त्रुटियों को पकड़ना चाहते हैं (उन्हें UI में प्रदर्शित होने से रोकने के लिए, या बैच कार्य को चालू रखने के लिए)। इन मामलों में, आप सामान्य Exception
(या Throwable
) पकड़ सकते हैं और त्रुटि को उचित तरीके से संभाल सकते हैं। हालांकि, ऐसा करने से पहले ध्यान से सोचें, और इस संदर्भ में यह सुरक्षित क्यों है, यह समझाते हुए टिप्पणी करें।
सामान्य अपवादों को पकड़ने के विकल्प:
- मल्टी-कैच ब्लॉक के हिस्से के रूप में प्रत्येक अपवाद को अलग से पकड़ें, उदाहरण के लिए:
try { ... } catch (ClassNotFoundException | NoSuchMethodException e) { ... }
- एकाधिक कोशिश ब्लॉक के साथ, अधिक बढ़िया त्रुटि प्रबंधन के लिए अपने कोड को दोबारा प्रतिक्रिया दें। आईओ को पार्सिंग से अलग करें, और प्रत्येक मामले में त्रुटियों को अलग से संभालें।
- अपवाद को वापस लें। कई बार आपको इस स्तर पर वैसे भी अपवाद को पकड़ने की आवश्यकता नहीं होती है, बस विधि को इसे फेंकने दें।
याद रखें कि अपवाद आपके मित्र हैं! जब संकलक शिकायत करता है कि आप एक अपवाद नहीं पकड़ रहे हैं, तो चिल्लाओ मत। मुस्कुराना! कंपाइलर ने आपके कोड में रनटाइम समस्याओं को पकड़ना आपके लिए आसान बना दिया है।
फाइनलाइज़र का प्रयोग न करें
जब कोई वस्तु कचरा एकत्र की जाती है, तो फ़ाइनलाइज़र कोड का एक हिस्सा निष्पादित करने का एक तरीका होता है। जबकि फ़ाइनलाइज़र क्लीनअप (विशेष रूप से बाहरी संसाधनों) के लिए उपयोगी हो सकते हैं, इस बात की कोई गारंटी नहीं है कि फ़ाइनलाइज़र को कब बुलाया जाएगा (या यहाँ तक कि इसे बिल्कुल भी कॉल किया जाएगा)।
एंड्रॉइड फाइनलाइजर्स का उपयोग नहीं करता है। ज्यादातर मामलों में, आप इसके बजाय अच्छे अपवाद प्रबंधन का उपयोग कर सकते हैं। यदि आपको पूरी तरह से अंतिम रूप देने की आवश्यकता है, तो एक close()
विधि (या पसंद) को परिभाषित करें और उस विधि को कॉल करने की आवश्यकता होने पर दस्तावेज़ ठीक करें (उदाहरण के लिए इनपुटस्ट्रीम देखें)। इस मामले में, यह उचित है लेकिन फाइनलाइज़र से एक छोटा लॉग संदेश प्रिंट करने की आवश्यकता नहीं है, जब तक कि लॉग बाढ़ की उम्मीद न हो।
पूरी तरह से योग्य आयात
जब आप पैकेज बार से foo
Bar
का उपयोग करना चाहते हैं, तो इसे आयात करने के दो संभावित तरीके हैं:
-
import foo.*;
संभावित रूप से आयात विवरणों की संख्या कम कर देता है।
-
import foo.Bar;
यह स्पष्ट करता है कि किन वर्गों का उपयोग किया जाता है और रखरखावकर्ताओं के लिए कोड अधिक पठनीय है।
import foo.Bar;
सभी Android कोड आयात करने के लिए। जावा मानक पुस्तकालयों ( java.util.*
, java.io.*
, आदि.) और इकाई परीक्षण कोड ( junit.framework.*
) के लिए एक स्पष्ट अपवाद बनाया गया है।
जावा पुस्तकालय नियम
एंड्रॉइड के जावा पुस्तकालयों और उपकरणों का उपयोग करने के लिए सम्मेलन हैं। कुछ मामलों में, सम्मेलन महत्वपूर्ण तरीकों से बदल गया है और पुराने कोड एक पदावनत पैटर्न या पुस्तकालय का उपयोग कर सकते हैं। ऐसे कोड के साथ काम करते समय, मौजूदा शैली को जारी रखना ठीक है। हालाँकि, नए घटक बनाते समय, कभी भी पदावनत पुस्तकालयों का उपयोग न करें।
जावा शैली के नियम
जावाडोक मानक टिप्पणियों का प्रयोग करें
प्रत्येक फ़ाइल में सबसे ऊपर एक कॉपीराइट स्टेटमेंट होना चाहिए, उसके बाद पैकेज और इंपोर्ट स्टेटमेंट (प्रत्येक ब्लॉक को एक खाली लाइन द्वारा अलग किया गया), और अंत में क्लास या इंटरफ़ेस डिक्लेरेशन होना चाहिए। Javadoc टिप्पणियों में, वर्णन करें कि वर्ग या इंटरफ़ेस क्या करता है।
/* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.foo; import android.os.Blah; import android.view.Yada; import java.sql.ResultSet; import java.sql.SQLException; /** * Does X and Y and provides an abstraction for Z. */ public class Foo { ... }
आपके द्वारा लिखे जाने वाले प्रत्येक वर्ग और गैर-सार्वजनिक सार्वजनिक पद्धति में कम से कम एक वाक्य के साथ जावाडोक टिप्पणी होनी चाहिए जो यह बताए कि कक्षा या विधि क्या करती है। यह वाक्य तीसरे व्यक्ति वर्णनात्मक क्रिया से शुरू होना चाहिए।
उदाहरण
/** Returns the correctly rounded positive square root of a double value. */ static double sqrt(double a) { ... }
या
/** * Constructs a new String by converting the specified array of * bytes using the platform's default character encoding. */ public String(byte[] bytes) { ... }
यदि आपके सभी Javadoc कहते हैं कि "सेट फू" है, तो आपको तुच्छ प्राप्त करने और सेट करने के तरीकों जैसे कि setFoo()
के लिए Javadoc लिखने की आवश्यकता नहीं है। यदि विधि कुछ अधिक जटिल करती है (जैसे कि एक बाधा को लागू करना या इसका कोई महत्वपूर्ण दुष्प्रभाव है), तो आपको इसे अवश्य ही प्रलेखित करना चाहिए। यदि यह स्पष्ट नहीं है कि संपत्ति "फू" का क्या अर्थ है, तो आपको इसे दस्तावेज करना चाहिए।
आपके द्वारा लिखी जाने वाली हर विधि, सार्वजनिक या अन्यथा, Javadoc से लाभान्वित होगी। सार्वजनिक विधियाँ एक एपीआई का हिस्सा हैं और इसलिए Javadoc की आवश्यकता होती है। Android Javadoc टिप्पणियाँ लिखने के लिए कोई विशिष्ट शैली लागू नहीं करता है, लेकिन आपको Javadoc टूल के लिए दस्तावेज़ टिप्पणियाँ कैसे लिखें में दिए गए निर्देशों का पालन करना चाहिए।
संक्षिप्त विधियाँ लिखिए
जब संभव हो, तरीकों को छोटा और केंद्रित रखें। हम मानते हैं कि लंबी विधियाँ कभी-कभी उपयुक्त होती हैं, इसलिए विधि की लंबाई पर कोई कठोर सीमा नहीं रखी गई है। यदि कोई विधि 40 या अधिक पंक्तियों से अधिक है, तो इस बारे में सोचें कि क्या इसे प्रोग्राम की संरचना को नुकसान पहुँचाए बिना तोड़ा जा सकता है।
फ़ील्ड को मानक स्थानों में परिभाषित करें
फ़ील्ड को या तो फ़ाइल के शीर्ष पर या उनका उपयोग करने वाली विधियों से ठीक पहले परिभाषित करें।
परिवर्तनीय दायरा सीमित करें
स्थानीय चरों का दायरा कम से कम रखें। यह आपके कोड की पठनीयता और रखरखाव को बढ़ाता है और त्रुटि की संभावना को कम करता है। प्रत्येक चर को अंतरतम ब्लॉक में घोषित करें जो चर के सभी उपयोगों को संलग्न करता है।
स्थानीय चर को उस बिंदु पर घोषित करें जहां उनका पहली बार उपयोग किया जाता है। लगभग हर स्थानीय चर घोषणा में एक इनिशियलाइज़र होना चाहिए। यदि आपके पास अभी तक एक चर को समझदारी से आरंभ करने के लिए पर्याप्त जानकारी नहीं है, तो घोषणा को तब तक के लिए स्थगित कर दें जब तक आप ऐसा नहीं करते।
अपवाद ट्राइ-कैच स्टेटमेंट है। यदि एक चर को एक विधि के वापसी मूल्य के साथ आरंभीकृत किया जाता है जो एक जाँच अपवाद को फेंकता है, तो इसे एक कोशिश ब्लॉक के अंदर आरंभीकृत किया जाना चाहिए। यदि मान का उपयोग try ब्लॉक के बाहर किया जाना चाहिए, तो इसे try ब्लॉक से पहले घोषित किया जाना चाहिए, जहाँ इसे अभी तक समझदारी से आरंभ नहीं किया जा सकता है:
// Instantiate class cl, which represents some sort of Set Set s = null; try { s = (Set) cl.newInstance(); } catch(IllegalAccessException e) { throw new IllegalArgumentException(cl + " not accessible"); } catch(InstantiationException e) { throw new IllegalArgumentException(cl + " not instantiable"); } // Exercise the set s.addAll(Arrays.asList(args));
हालाँकि, आप एक विधि में ट्राइ-कैच ब्लॉक को एनकैप्सुलेट करके भी इस मामले से बच सकते हैं:
Set createSet(Class cl) { // Instantiate class cl, which represents some sort of Set try { return (Set) cl.newInstance(); } catch(IllegalAccessException e) { throw new IllegalArgumentException(cl + " not accessible"); } catch(InstantiationException e) { throw new IllegalArgumentException(cl + " not instantiable"); } } ... // Exercise the set Set s = createSet(cl); s.addAll(Arrays.asList(args));
जब तक अन्यथा करने के लिए कोई सम्मोहक कारण न हो, तब तक स्टेटमेंट के लिए लूप वेरिएबल्स की घोषणा करें:
for (int i = 0; i < n; i++) { doSomething(i); }
तथा
for (Iterator i = c.iterator(); i.hasNext(); ) { doSomethingElse(i.next()); }
आदेश आयात विवरण
आयात विवरणों का क्रम है:
- Android आयात
- तृतीय पक्षों से आयात (
com
,junit
,net
,org
) -
java
औरjavax
आईडीई सेटिंग्स से पूरी तरह मेल खाने के लिए, आयात होना चाहिए:
- प्रत्येक समूह के भीतर वर्णमाला, छोटे अक्षरों से पहले पूंजी अक्षरों के साथ (उदाहरण के लिए, जेड पहले ए)
- प्रत्येक प्रमुख समूह (
android
,com
,junit
,net
,org
,java
,javax
) के बीच एक रिक्त रेखा द्वारा अलग किया गया
मूल रूप से, आदेश देने पर कोई शैली की आवश्यकता नहीं थी, जिसका अर्थ है कि आईडीई या तो हमेशा क्रम बदल रहे थे या आईडीई डेवलपर्स को स्वत: आयात प्रबंधन सुविधाओं को अक्षम करना पड़ा और आयात को मैन्युअल रूप से बनाए रखना पड़ा। यह बुरा समझा गया। जब जावा-शैली से पूछा गया, तो पसंदीदा शैलियों में बेतहाशा भिन्नता थी और यह Android के लिए "आदेश देने और सुसंगत रहने" की आवश्यकता के लिए नीचे आ गया। इसलिए हमने एक शैली चुनी, शैली मार्गदर्शिका को अपडेट किया और आईडीई को इसका पालन करने के लिए मजबूर किया। हम उम्मीद करते हैं कि चूंकि आईडीई उपयोगकर्ता कोड पर काम करते हैं, इसलिए सभी पैकेजों में आयात बिना किसी अतिरिक्त इंजीनियरिंग प्रयास के इस पैटर्न से मेल खाएगा।
हमने इस शैली को इस प्रकार चुना है कि:
- लोग जिन आयातों को पहले देखना चाहते हैं वे सबसे ऊपर (
android
) होते हैं। - जो आयात लोग कम से कम देखना चाहते हैं वे सबसे नीचे (
java
) होते हैं। - मनुष्य आसानी से शैली का अनुसरण कर सकते हैं।
- आईडीई शैली का पालन कर सकते हैं।
स्थिर आयातों को अन्य सभी आयातों से ऊपर रखें, जिस तरह से नियमित आयातों का आदेश दिया जाता है।
इंडेंटेशन के लिए रिक्त स्थान का प्रयोग करें
हम ब्लॉक के लिए चार (4) स्पेस इंडेंट का उपयोग करते हैं और टैब का कभी नहीं। जब संदेह हो, तो आसपास के कोड के अनुरूप रहें।
हम फ़ंक्शन कॉल और असाइनमेंट सहित लाइन रैप्स के लिए आठ (8) स्पेस इंडेंट का उपयोग करते हैं।
अनुशंसित
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
सिफारिश नहीं की गई
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
फील्ड नामकरण परंपराओं का पालन करें
- गैर-सार्वजनिक, गैर-स्थैतिक फ़ील्ड नाम
m
से शुरू होते हैं। - स्थैतिक क्षेत्र के नाम
s
से शुरू होते हैं। - अन्य क्षेत्र छोटे अक्षर से शुरू होते हैं।
- स्थैतिक अंतिम फ़ील्ड (स्थिर, गहराई से अपरिवर्तनीय)
ALL_CAPS_WITH_UNDERSCORES
हैं।
उदाहरण के लिए:
public class MyClass { public static final int SOME_CONSTANT = 42; public int publicField; private static MyClass sSingleton; int mPackagePrivate; private int mPrivate; protected int mProtected; }
मानक ब्रेस शैली का प्रयोग करें
उनके सामने कोड के समान लाइन पर ब्रेसिज़ लगाएं, उनकी अपनी लाइन पर नहीं:
class MyClass { int func() { if (something) { // ... } else if (somethingElse) { // ... } else { // ... } } }
हमें सशर्त के लिए बयानों के चारों ओर ब्रेसिज़ की आवश्यकता होती है। अपवाद: यदि संपूर्ण सशर्त (स्थिति और शरीर) एक पंक्ति में फिट होते हैं, तो आप इसे एक पंक्ति में रख सकते हैं (लेकिन इसके लिए बाध्य नहीं हैं)। उदाहरण के लिए, यह स्वीकार्य है:
if (condition) { body(); }
और यह स्वीकार्य है:
if (condition) body();
लेकिन यह स्वीकार्य नहीं है:
if (condition) body(); // bad!
लाइन की लंबाई सीमित करें
आपके कोड में पाठ की प्रत्येक पंक्ति अधिकतम 100 वर्ण लंबी होनी चाहिए। हालांकि इस नियम के बारे में काफी चर्चा हुई है, निर्णय यह है कि निम्नलिखित अपवादों के साथ 100 वर्ण अधिकतम हैं:
- यदि किसी टिप्पणी पंक्ति में एक उदाहरण कमांड या शाब्दिक URL 100 वर्णों से अधिक लंबा है, तो वह पंक्ति कट और पेस्ट की आसानी के लिए 100 वर्णों से अधिक लंबी हो सकती है।
- आयात लाइनें सीमा से अधिक हो सकती हैं क्योंकि मनुष्य उन्हें शायद ही कभी देखते हैं (यह उपकरण लेखन को भी सरल करता है)।
मानक जावा एनोटेशन का प्रयोग करें
एनोटेशन को समान भाषा तत्व के लिए अन्य संशोधक से पहले होना चाहिए। सरल मार्कर एनोटेशन (उदाहरण के लिए, @Override
) को भाषा तत्व के साथ एक ही पंक्ति में सूचीबद्ध किया जा सकता है। यदि कई एनोटेशन हैं, या पैरामीटरयुक्त एनोटेशन हैं, तो उन्हें वर्णानुक्रम में एक-प्रति-पंक्ति सूचीबद्ध करें।
जावा में तीन पूर्वनिर्धारित एनोटेशन के लिए Android मानक अभ्यास हैं:
- जब भी एनोटेट तत्व का उपयोग हतोत्साहित किया जाता है तो
@Deprecated
एनोटेशन का उपयोग करें। यदि आप@Deprecated
एनोटेशन का उपयोग करते हैं, तो आपके पास@deprecated
Javadoc टैग भी होना चाहिए और इसे वैकल्पिक कार्यान्वयन का नाम देना चाहिए। इसके अलावा, याद रखें कि एक@Deprecated
विधि अभी भी काम करने वाली है । यदि आपको पुराना कोड दिखाई देता है जिसमें@deprecated
Javadoc टैग है, तो@Deprecated
एनोटेशन जोड़ें। - जब भी कोई विधि
@Override
से घोषणा या कार्यान्वयन को ओवरराइड करती है तो @Override एनोटेशन का उपयोग करें। उदाहरण के लिए, यदि आप@inheritdocs
Javadoc टैग का उपयोग करते हैं, और एक वर्ग (इंटरफ़ेस नहीं) से प्राप्त करते हैं, तो आपको यह भी टिप्पणी करनी होगी कि विधि मूल वर्ग की विधि को ओवरराइड करती है। -
@SuppressWarnings
एनोटेशन का उपयोग केवल उन परिस्थितियों में करें जहां चेतावनी को समाप्त करना असंभव है। यदि कोई चेतावनी इस "समाप्त करना असंभव" परीक्षण को पास कर लेती है, तो@SuppressWarnings
एनोटेशन का उपयोग यह सुनिश्चित करने के लिए किया जाना चाहिए कि सभी चेतावनियाँ कोड में वास्तविक समस्याओं को दर्शाती हैं।जब
@SuppressWarnings
एनोटेशन आवश्यक हो, तो इसेTODO
टिप्पणी के साथ उपसर्ग किया जाना चाहिए जो "समाप्त करना असंभव" स्थिति की व्याख्या करता है। यह आम तौर पर एक आपत्तिजनक वर्ग की पहचान करता है जिसमें एक अजीब इंटरफ़ेस होता है। उदाहरण के लिए:// TODO: The third-party class com.third.useful.Utility.rotate() needs generics @SuppressWarnings("generic-cast") List<String> blix = Utility.rotate(blax);
जब
@SuppressWarnings
एनोटेशन की आवश्यकता होती है, तो सॉफ़्टवेयर तत्वों को अलग करने के लिए कोड को रिफैक्टर करें जहां एनोटेशन लागू होता है।
संक्षिप्त शब्दों को शब्दों के रूप में समझें
नामों को और अधिक पठनीय बनाने के लिए नामकरण चर, विधियों और कक्षाओं में शब्दों के रूप में परिवर्णी शब्द और संक्षिप्त रूप का इलाज करें:
अच्छा | बुरा |
---|---|
XmlHttpRequest | XMLHTTPRequest |
getCustomerId | getCustomerID |
वर्ग एचटीएमएल | कक्षा एचटीएमएल |
स्ट्रिंग यूआरएल | स्ट्रिंग यूआरएल |
लंबी आईडी | लंबी आईडी |
जैसा कि JDK और Android कोड आधार दोनों समरूपों के आसपास असंगत हैं, आसपास के कोड के अनुरूप होना लगभग असंभव है। इसलिए, संक्षिप्त शब्दों को हमेशा शब्दों के रूप में लें।
TODO टिप्पणियों का उपयोग करें
कोड के लिए TODO
टिप्पणियों का उपयोग करें जो अस्थायी है, एक अल्पकालिक समाधान है, या पर्याप्त अच्छा है लेकिन सही नहीं है। इन टिप्पणियों में सभी बड़े अक्षरों में स्ट्रिंग TODO
शामिल होना चाहिए, उसके बाद एक कोलन होना चाहिए:
// TODO: Remove this code after the UrlTable2 has been checked in.
तथा
// TODO: Change this to use a flag instead of a constant.
यदि आपका TODO
"भविष्य की तारीख में कुछ करें" के रूप में है, तो सुनिश्चित करें कि आप या तो एक विशिष्ट तिथि ("नवंबर 2005 तक ठीक करें") या एक विशिष्ट घटना शामिल करें ("सभी प्रोडक्शन मिक्सर प्रोटोकॉल V7 को समझने के बाद इस कोड को हटा दें।" ).
संभल कर लॉग इन करें
जबकि लॉगिंग आवश्यक है, इसका प्रदर्शन पर नकारात्मक प्रभाव पड़ता है और यथोचित रूप से न रखने पर इसकी उपयोगिता खो जाती है। लॉगिंग सुविधाएं लॉगिंग के पांच अलग-अलग स्तर प्रदान करती हैं:
-
ERROR
: कुछ घातक होने पर उपयोग करें, अर्थात, कुछ के उपयोगकर्ता-दृश्य परिणाम होंगे और कुछ डेटा को हटाने, ऐप्स को अनइंस्टॉल करने, डेटा विभाजन को पोंछने, या पूरे डिवाइस को फिर से चमकाने (या बदतर) के बिना पुनर्प्राप्त करने योग्य नहीं होगा। यह स्तर हमेशा लॉग होता है। समस्याएँ जोERROR
स्तर पर कुछ लॉगिंग को सही ठहराती हैं, एक सांख्यिकी-एकत्रित करने वाले सर्वर को रिपोर्ट किए जाने वाले अच्छे उम्मीदवार हैं। -
WARNING
: कुछ गंभीर और अनपेक्षित होने पर उपयोग करें, यानी, कुछ ऐसा जिसके परिणाम उपयोगकर्ता को दिखाई देंगे लेकिन कुछ स्पष्ट कार्रवाई करके डेटा हानि के बिना पुनर्प्राप्त करने योग्य होने की संभावना है, प्रतीक्षा करने या किसी ऐप को फिर से डाउनलोड करने के लिए फिर से शुरू करने से लेकर ऐप का नया संस्करण या डिवाइस को रीबूट करना। यह स्तर हमेशा लॉग होता है।WARNING
स्तर पर लॉगिंग को उचित ठहराने वाली समस्याओं पर भी सांख्यिकी-एकत्रित करने वाले सर्वर को रिपोर्ट करने के लिए विचार किया जा सकता है। -
INFORMATIVE
: ध्यान देने के लिए उपयोग करें कि कुछ दिलचस्प हुआ है, यानी, जब ऐसी स्थिति का पता चला है जिसका व्यापक प्रभाव होने की संभावना है, हालांकि जरूरी नहीं कि यह एक त्रुटि हो। ऐसी स्थिति को केवल उस मॉड्यूल द्वारा लॉग किया जाना चाहिए जो मानता है कि यह उस डोमेन में सबसे अधिक आधिकारिक है (गैर-आधिकारिक घटकों द्वारा डुप्लिकेट लॉगिंग से बचने के लिए)। यह स्तर हमेशा लॉग होता है। -
DEBUG
: डिवाइस पर क्या हो रहा है, इस पर आगे ध्यान देने के लिए उपयोग करें जो अनपेक्षित व्यवहारों की जांच और डीबग करने के लिए प्रासंगिक हो सकता है। आपके घटक के साथ क्या हो रहा है, इसके बारे में पर्याप्त जानकारी एकत्र करने के लिए केवल वही लॉग करें जो आवश्यक है। यदि आपका डीबग लॉग लॉग पर हावी हो रहा है, तो आपको वर्बोज़ लॉगिंग का उपयोग करना चाहिए।रिलीज बिल्ड पर भी यह स्तर लॉग किया गया है, और एक
if (LOCAL_LOG)
याif LOCAL_LOGD)
ब्लॉक से घिरा होना आवश्यक है, जहांLOCAL_LOG[D]
को आपकी कक्षा या उपघटक में परिभाषित किया गया है, ताकि ऐसे सभी लॉगिंग को अक्षम करने की संभावना हो . इसलिए,if (LOCAL_LOG)
ब्लॉक में कोई सक्रिय तर्क नहीं होना चाहिए। लॉग के लिए सभी स्ट्रिंग बिल्डिंग कोif (LOCAL_LOG)
ब्लॉक के अंदर भी रखा जाना चाहिए। लॉगिंग कॉल को मेथड कॉल में रिफैक्टर न करें यदि यह स्ट्रिंग बिल्डिंग कोif (LOCAL_LOG)
ब्लॉक के बाहर होने वाला है।कुछ कोड है जो अभी भी
if (localLOGV)
कहता है। यह भी स्वीकार्य माना जाता है, हालांकि नाम अमानक है। -
VERBOSE
: अन्य सभी चीज़ों के लिए उपयोग करें। यह स्तर केवल डिबग बिल्ड पर लॉग किया गया है और इसेif (LOCAL_LOGV)
ब्लॉक (या समतुल्य) से घिरा होना चाहिए ताकि इसे डिफ़ॉल्ट रूप से संकलित किया जा सके। किसी भी स्ट्रिंग बिल्डिंग को रिलीज बिल्ड से बाहर कर दिया गया है औरif (LOCAL_LOGV)
ब्लॉक के अंदर दिखाई देने की जरूरत है।
टिप्पणियाँ
- किसी दिए गए मॉड्यूल के भीतर,
VERBOSE
स्तर के अलावा, यदि संभव हो तो केवल एक बार त्रुटि की सूचना दी जानी चाहिए। एक मॉड्यूल के भीतर फ़ंक्शन कॉल की एक श्रृंखला के भीतर, केवल अंतरतम फ़ंक्शन को त्रुटि वापस करनी चाहिए, और उसी मॉड्यूल में कॉल करने वालों को केवल कुछ लॉगिंग जोड़नी चाहिए यदि यह समस्या को अलग करने में महत्वपूर्ण रूप से मदद करता है। - मॉड्यूल की एक श्रृंखला में,
VERBOSE
स्तर के अलावा, जब एक निम्न-स्तरीय मॉड्यूल उच्च-स्तरीय मॉड्यूल से आने वाले अमान्य डेटा का पता लगाता है, तो निम्न-स्तरीय मॉड्यूल को इस स्थिति को केवलDEBUG
लॉग में लॉग करना चाहिए, और केवल लॉगिंग प्रदान करता है वह जानकारी जो कॉल करने वाले के लिए अन्यथा उपलब्ध नहीं है। विशेष रूप से, ऐसी स्थितियों को लॉग करने की कोई आवश्यकता नहीं है जहाँ एक अपवाद फेंका जाता है (अपवाद में सभी प्रासंगिक जानकारी शामिल होनी चाहिए), या जहाँ लॉग की जा रही एकमात्र जानकारी एक त्रुटि कोड में निहित है। यह फ़्रेमवर्क और ऐप्स के बीच इंटरेक्शन में विशेष रूप से महत्वपूर्ण है, और तृतीय-पक्ष ऐप्स के कारण होने वाली स्थितियाँ जो फ़्रेमवर्क द्वारा ठीक से प्रबंधित की जाती हैं, उन्हेंDEBUG
स्तर से अधिक लॉगिंग ट्रिगर नहीं करना चाहिए।INFORMATIVE
स्तर या उच्चतर पर लॉगिंग को ट्रिगर करने वाली एकमात्र स्थिति तब होती है जब कोई मॉड्यूल या ऐप अपने स्तर पर या निचले स्तर से आने वाली त्रुटि का पता लगाता है। - जब ऐसी स्थिति जो सामान्य रूप से कुछ लॉगिंग को उचित ठहराती है, कई बार होने की संभावना होती है, तो उसी (या बहुत समान) जानकारी की कई डुप्लिकेट प्रतियों के साथ लॉग को ओवरफ्लो करने से रोकने के लिए कुछ दर-सीमित तंत्र को लागू करना एक अच्छा विचार हो सकता है।
- नेटवर्क कनेक्टिविटी के नुकसान को सामान्य माना जाता है और इसकी पूरी तरह से उम्मीद की जाती है, और इसे अनावश्यक रूप से लॉग नहीं किया जाना चाहिए। नेटवर्क कनेक्टिविटी का नुकसान जिसका किसी ऐप के भीतर परिणाम होता है, उसे
DEBUG
याVERBOSE
स्तर पर लॉग किया जाना चाहिए (इस पर निर्भर करता है कि क्या परिणाम काफी गंभीर हैं और अनपेक्षित रूप से रिलीज़ बिल्ड में लॉग इन करने के लिए पर्याप्त हैं)। - किसी फ़ाइल सिस्टम पर एक पूर्ण फ़ाइल सिस्टम होना जो कि तृतीय-पक्ष ऐप्स के लिए या उनकी ओर से पहुँच योग्य है, को सूचनात्मक से उच्च स्तर पर लॉग नहीं किया जाना चाहिए।
- किसी भी अविश्वसनीय स्रोत से आने वाला अमान्य डेटा (साझा भंडारण पर किसी भी फ़ाइल, या नेटवर्क कनेक्शन के माध्यम से आने वाले डेटा सहित) को अपेक्षित माना जाता है और इसे अमान्य होने का पता चलने पर
DEBUG
से उच्च स्तर पर किसी भी लॉगिंग को ट्रिगर नहीं करना चाहिए (और तब भी लॉगिंग जितना संभव हो उतना सीमित होना चाहिए)। - जब
String
ऑब्जेक्ट्स पर उपयोग किया जाता है, तो+
ऑपरेटर निश्चित रूप से डिफ़ॉल्ट बफर आकार (16 वर्ण) और संभावित रूप से अन्य अस्थायीString
ऑब्जेक्ट्स के साथStringBuilder
उदाहरण बनाता है। तो स्पष्ट रूप सेStringBuilder
ऑब्जेक्ट्स बनाना डिफ़ॉल्ट+
ऑपरेटर पर निर्भर होने से अधिक महंगा नहीं है (और यह बहुत अधिक कुशल हो सकता है)। ध्यान रखें किLog.v()
को कॉल करने वाला कोड संकलित और रिलीज़ बिल्ड पर निष्पादित होता है, जिसमें स्ट्रिंग्स का निर्माण शामिल है, भले ही लॉग पढ़े नहीं जा रहे हों। - कोई भी लॉगिंग जो अन्य लोगों द्वारा पढ़ने के लिए है और रिलीज़ बिल्ड में उपलब्ध होने के लिए गूढ़ होने के बिना संक्षिप्त होना चाहिए, और समझने योग्य होना चाहिए। इसमें
DEBUG
स्तर तक सभी लॉगिंग शामिल हैं। - जब संभव हो, एक ही लाइन पर लॉगिंग करते रहें। लाइन की लंबाई 80 या 100 वर्णों तक स्वीकार्य है। यदि संभव हो तो लगभग 130 या 160 वर्णों (टैग की लंबाई सहित) से अधिक लंबाई से बचें।
- यदि लॉगिंग रिपोर्ट सफल हो जाती है, तो इसे कभी भी
VERBOSE
से ऊंचे स्तर पर उपयोग न करें। - यदि आप किसी ऐसी समस्या का निदान करने के लिए अस्थायी लॉगिंग का उपयोग कर रहे हैं जिसे पुन: उत्पन्न करना कठिन है, तो इसे
DEBUG
याVERBOSE
स्तर पर रखें और इसे if ब्लॉक्स के साथ संलग्न करें जो संकलन समय पर इसे अक्षम करने की अनुमति देते हैं। - लॉग के माध्यम से सुरक्षा रिसाव के बारे में सावधान रहें। निजी जानकारी लॉगिंग से बचें। विशेष रूप से, सुरक्षित सामग्री के बारे में लॉगिंग जानकारी से बचें। फ्रेमवर्क कोड लिखते समय यह विशेष रूप से महत्वपूर्ण है क्योंकि यह पहले से जानना आसान नहीं है कि निजी जानकारी या संरक्षित सामग्री क्या होगी और क्या नहीं।
- कभी भी
System.out.println()
(याprintf()
मूल कोड के लिए) का उपयोग न करें।System.out
औरSystem.err
को/dev/null
पर पुनर्निर्देशित किया जाता है, इसलिए आपके प्रिंट स्टेटमेंट का कोई दृश्य प्रभाव नहीं होता है। हालाँकि, इन कॉल्स के लिए होने वाली सभी स्ट्रिंग बिल्डिंग अभी भी निष्पादित हो जाती हैं। - लॉगिंग का सुनहरा नियम यह है कि आपके लॉग अनावश्यक रूप से अन्य लॉग को बफर से बाहर नहीं धकेल सकते हैं, जैसे अन्य लोग आपके लॉग को बाहर नहीं कर सकते हैं।
Javatests शैली नियम
परीक्षण विधि नामकरण परंपराओं का पालन करें और परीक्षण किए जा रहे विशिष्ट मामले से परीक्षण की जा रही चीज़ों को अलग करने के लिए अंडरस्कोर का उपयोग करें। यह शैली यह देखना आसान बनाती है कि किन मामलों का परीक्षण किया जा रहा है। उदाहरण के लिए:
testMethod_specificCase1 testMethod_specificCase2 void testIsDistinguishable_protanopia() { ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA) assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK)) assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y)) }