योगदानकर्ताओं के लिए AOSP जावा कोड शैली

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

निरतंरता बनाए रखें

सबसे सरल नियमों में से एक है BE CONSISTENT। यदि आप कोड संपादित कर रहे हैं, तो आसपास के कोड को देखने और उसकी शैली निर्धारित करने के लिए कुछ मिनट दें। यदि वह कोड 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) {
        ...
    }
  • एकाधिक प्रयास ब्लॉकों के साथ, अधिक बढ़िया त्रुटि प्रबंधन के लिए अपने कोड को दोबारा दोहराएं। आईओ को पार्सिंग से विभाजित करें, और प्रत्येक मामले में त्रुटियों को अलग से संभालें।
  • अपवाद को फिर से फेंको। वैसे भी कई बार आपको इस स्तर पर अपवाद को पकड़ने की आवश्यकता नहीं होती है, बस विधि को इसे फेंकने दें।

याद रखें कि अपवाद आपके मित्र हैं! जब संकलक शिकायत करता है कि आप अपवाद नहीं पकड़ रहे हैं, तो चिल्लाओ मत। मुस्कान! कंपाइलर ने आपके कोड में रनटाइम समस्याओं को पकड़ना आपके लिए आसान बना दिया है।

फ़ाइनलाइज़र का उपयोग न करें

फ़ाइनलाइज़र एक तरह से कोड का एक हिस्सा निष्पादित करने का एक तरीका है जब कोई वस्तु कचरा एकत्र किया जाता है। जबकि फ़ाइनलाइज़र क्लीनअप (विशेष रूप से बाहरी संसाधनों के लिए) के लिए आसान हो सकते हैं, इस बात की कोई गारंटी नहीं है कि फ़ाइनलाइज़र को कब बुलाया जाएगा (या यहाँ तक कि इसे बिल्कुल भी कहा जाएगा)।

Android फ़ाइनलाइज़र का उपयोग नहीं करता है। ज्यादातर मामलों में, आप इसके बजाय अच्छे अपवाद हैंडलिंग का उपयोग कर सकते हैं। यदि आपको पूरी तरह से फाइनलाइज़र की आवश्यकता है, तो एक close() विधि (या पसंद) और दस्तावेज़ को ठीक उसी समय परिभाषित करें जब उस विधि को कॉल करने की आवश्यकता हो (उदाहरण के लिए इनपुटस्ट्रीम देखें)। इस मामले में, फ़ाइनलाइज़र से लघु लॉग संदेश को प्रिंट करना उचित है, लेकिन इसकी आवश्यकता नहीं है, जब तक कि लॉग्स में बाढ़ आने की उम्मीद नहीं है।

पूरी तरह से योग्य आयात

जब आप पैकेज foo से क्लास Bar का उपयोग करना चाहते हैं, तो इसे आयात करने के दो संभावित तरीके हैं:

  • import foo.*;

    संभावित रूप से आयात विवरणों की संख्या को कम करता है।

  • import foo.Bar;

    यह स्पष्ट करता है कि किन वर्गों का उपयोग किया जाता है और कोड अनुरक्षकों के लिए अधिक पठनीय है।

import foo.Bar; सभी Android कोड आयात करने के लिए। जावा मानक पुस्तकालयों ( java.util.* , java.io.* , आदि) और इकाई परीक्षण कोड ( junit.framework.* ) के लिए एक स्पष्ट अपवाद बनाया गया है।

जावा पुस्तकालय नियम

एंड्रॉइड के जावा पुस्तकालयों और उपकरणों का उपयोग करने के लिए परंपराएं हैं। कुछ मामलों में, सम्मेलन महत्वपूर्ण तरीकों से बदल गया है और पुराना कोड एक बहिष्कृत पैटर्न या पुस्तकालय का उपयोग कर सकता है। ऐसे कोड के साथ काम करते समय, मौजूदा शैली को जारी रखना ठीक है। हालांकि, नए घटक बनाते समय, कभी भी बहिष्कृत पुस्तकालयों का उपयोग न करें।

जावा शैली नियम

जावाडोक मानक टिप्पणियों का प्रयोग करें

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

/*
 * Copyright 2022 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) {
    ...
}

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

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

संक्षिप्त तरीके लिखें

जब संभव हो, तरीकों को छोटा और केंद्रित रखें। हम मानते हैं कि लंबी विधियाँ कभी-कभी उपयुक्त होती हैं, इसलिए विधि की लंबाई पर कोई कठोर सीमा नहीं रखी जाती है। यदि कोई विधि 40 पंक्तियों से अधिक है, तो इस बारे में सोचें कि क्या कार्यक्रम की संरचना को नुकसान पहुंचाए बिना इसे तोड़ा जा सकता है।

फ़ील्ड को मानक स्थानों में परिभाषित करें

फ़ाइल के शीर्ष पर या उनका उपयोग करने वाली विधियों से ठीक पहले फ़ील्ड को परिभाषित करें।

परिवर्तनीय दायरा सीमित करें

स्थानीय चरों का दायरा न्यूनतम रखें। यह आपके कोड की पठनीयता और रखरखाव को बढ़ाता है और त्रुटि की संभावना को कम करता है। प्रत्येक चर को अंतरतम ब्लॉक में घोषित करें जो चर के सभी उपयोगों को संलग्न करता है।

स्थानीय चरों को उस बिंदु पर घोषित करें जहां उनका पहली बार उपयोग किया जाता है। लगभग हर स्थानीय चर घोषणा में एक प्रारंभकर्ता होना चाहिए। यदि आपके पास अभी तक किसी वैरिएबल को समझदारी से प्रारंभ करने के लिए पर्याप्त जानकारी नहीं है, तो घोषणा को तब तक के लिए स्थगित कर दें जब तक आप ऐसा नहीं करते।

अपवाद ट्राइ-कैच स्टेटमेंट है। यदि एक वेरिएबल को चेक किए गए अपवाद को फेंकने वाली विधि के रिटर्न वैल्यू के साथ इनिशियलाइज़ किया जाता है, तो इसे एक try ब्लॉक के अंदर इनिशियलाइज़ किया जाना चाहिए। यदि मान को 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());
}

आदेश आयात विवरण

आयात विवरणों का क्रम है:

  1. Android आयात
  2. तृतीय पक्षों से आयात ( com , junit , net , org )
  3. java और javax

आईडीई सेटिंग्स से बिल्कुल मेल खाने के लिए, आयात होना चाहिए:

  • प्रत्येक समूह के भीतर वर्णानुक्रम, छोटे अक्षरों से पहले बड़े अक्षरों के साथ (उदाहरण के लिए, Z से पहले a)
  • प्रत्येक प्रमुख समूह ( android , com , junit , net , org , java , javax ) के बीच एक रिक्त रेखा से अलग

मूल रूप से, ऑर्डरिंग पर कोई स्टाइल आवश्यकता नहीं थी, जिसका अर्थ है कि आईडीई या तो हमेशा ऑर्डरिंग बदल रहे थे या आईडीई डेवलपर्स को स्वचालित आयात प्रबंधन सुविधाओं को अक्षम करना था और मैन्युअल रूप से आयात को बनाए रखना था। यह बुरा माना जाता था। जब जावा-शैली के बारे में पूछा गया, तो पसंदीदा शैलियों में बेतहाशा बदलाव आया और यह एंड्रॉइड के लिए नीचे आ गया, बस "एक ऑर्डर लेने और सुसंगत रहने" की आवश्यकता थी। इसलिए हमने एक स्टाइल चुना, स्टाइल गाइड को अपडेट किया, और आईडीई को इसका पालन कराया। हम उम्मीद करते हैं कि चूंकि IDE उपयोगकर्ता कोड पर काम करते हैं, सभी पैकेजों में आयात बिना किसी अतिरिक्त इंजीनियरिंग प्रयास के इस पैटर्न से मेल खाएगा।

हमने इस शैली को इस तरह चुना है कि:

  • लोग जिन आयातों को पहले देखना चाहते हैं, वे सबसे ऊपर ( 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 वर्ण हैं:

  • यदि किसी टिप्पणी पंक्ति में एक उदाहरण आदेश या 100 वर्णों से अधिक लंबा शाब्दिक URL है, तो कट और पेस्ट की आसानी के लिए वह पंक्ति 100 वर्णों से अधिक लंबी हो सकती है।
  • आयात लाइनें सीमा से अधिक हो सकती हैं क्योंकि मनुष्य उन्हें शायद ही कभी देखते हैं (यह उपकरण लेखन को भी सरल करता है)।

मानक जावा एनोटेशन का प्रयोग करें

एनोटेशन समान भाषा तत्व के लिए अन्य संशोधक से पहले होना चाहिए। साधारण मार्कर एनोटेशन (उदाहरण के लिए, @Override ) को भाषा तत्व के साथ एक ही लाइन पर सूचीबद्ध किया जा सकता है। यदि कई एनोटेशन, या पैरामीटरयुक्त एनोटेशन हैं, तो उन्हें वर्णानुक्रम में एक-प्रति-पंक्ति सूचीबद्ध करें।

जावा में तीन पूर्वनिर्धारित एनोटेशन के लिए एंड्रॉइड मानक अभ्यास हैं:

  • जब भी एनोटेट किए गए तत्व के उपयोग को हतोत्साहित किया जाता है, तो @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 एनोटेशन की आवश्यकता होती है, तो सॉफ़्टवेयर तत्वों को अलग करने के लिए कोड को रिफैक्टर करें जहां एनोटेशन लागू होता है।

शब्दकोष को शब्दों के रूप में समझें

नामों को और अधिक पठनीय बनाने के लिए नामकरण चर, विधियों और वर्गों में शब्दों के रूप में संक्षिप्त और संक्षिप्त रूप में व्यवहार करें:

अच्छा खराब
एक्सएमएलएचटीटीपीअनुरोध एक्सएमएलएचटीटीपीअनुरोध
ग्राहक आईडी प्राप्त करें ग्राहक आईडी प्राप्त करें
कक्षा एचटीएमएल कक्षा एचटीएमएल
स्ट्रिंग यूआरएल स्ट्रिंग यूआरएल
लंबी आईडी लंबी आईडी

चूंकि जेडीके और एंड्रॉइड कोड बेस दोनों ही समरूपों के आसपास असंगत हैं, इसलिए आसपास के कोड के अनुरूप होना लगभग असंभव है। इसलिए, शब्दकोष को हमेशा शब्दों के रूप में मानें।

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))
}