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

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

स्तिर रहो

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

इस नियम का दुर्लभ अपवाद परीक्षण कोड और शीर्ष-स्तरीय कोड है जहां आप सभी प्रकार की त्रुटियों को पकड़ना चाहते हैं (उन्हें यूआई में दिखने से रोकने के लिए, या बैच कार्य चालू रखने के लिए)। इन मामलों में, आप सामान्य Exception (या Throwable ) को पकड़ सकते हैं और त्रुटि को उचित रूप से संभाल सकते हैं। हालाँकि, ऐसा करने से पहले सावधानी से सोचें और टिप्पणी करके बताएं कि इस संदर्भ में यह सुरक्षित क्यों है।

सामान्य अपवाद पकड़ने के विकल्प:

  • मल्टी-कैच ब्लॉक के हिस्से के रूप में प्रत्येक अपवाद को अलग से पकड़ें, उदाहरण के लिए:
    try {
        ...
    } catch (ClassNotFoundException | NoSuchMethodException e) {
        ...
    }
  • एकाधिक प्रयास ब्लॉकों के साथ, अधिक सुक्ष्म त्रुटि प्रबंधन के लिए अपने कोड को दोबारा क्रियान्वित करें। पार्सिंग से IO को विभाजित करें, और प्रत्येक मामले में त्रुटियों को अलग से संभालें।
  • अपवाद पुनः फेंकें. कई बार आपको इस स्तर पर अपवाद को पकड़ने की ज़रूरत नहीं होती है, बस विधि को इसे फेंकने दें।

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

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

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

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

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

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

  • import foo.*;

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

  • import foo.Bar;

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

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

जावा लाइब्रेरी नियम

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

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

Javadoc मानक टिप्पणियों का उपयोग करें

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

/*
 * Copyright 2024 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() जैसी छोटी-मोटी get और set विधियों के लिए Javadoc लिखने की आवश्यकता नहीं है, यदि आपका संपूर्ण Javadoc "सेट्स Foo" कहेगा। यदि विधि कुछ अधिक जटिल कार्य करती है (जैसे कि किसी बाधा को लागू करना या इसका कोई महत्वपूर्ण दुष्प्रभाव होता है), तो आपको इसका दस्तावेजीकरण करना होगा। यदि यह स्पष्ट नहीं है कि संपत्ति "फू" का क्या अर्थ है, तो आपको इसका दस्तावेजीकरण करना चाहिए।

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

संक्षिप्त विधियाँ लिखिए

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

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

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

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

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

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

अपवाद ट्राई-कैच स्टेटमेंट है। यदि किसी वेरिएबल को किसी विधि के रिटर्न मान के साथ प्रारंभ किया गया है जो चेक किए गए अपवाद को फेंकता है, तो इसे प्रयास ब्लॉक के अंदर प्रारंभ किया जाना चाहिए। यदि मान का उपयोग प्रयास ब्लॉक के बाहर किया जाना चाहिए, तो इसे प्रयास ब्लॉक से पहले घोषित किया जाना चाहिए, जहां इसे अभी तक समझदारी से प्रारंभ नहीं किया जा सकता है:

// 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. एंड्रॉइड आयात करता है
  2. तीसरे पक्ष से आयात ( com , junit , net , org )
  3. java और javax

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

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

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

हमने यह शैली इस प्रकार चुनी कि:

  • जिन आयातों को लोग सबसे पहले देखना चाहते हैं वे सबसे ऊपर ( 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 एनोटेशन का उपयोग करें। उदाहरण के लिए, यदि आप @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
ग्राहक आईडी प्राप्त करें ग्राहक आईडी प्राप्त करें
क्लास एचटीएमएल क्लास एचटीएमएल
स्ट्रिंग यूआरएल स्ट्रिंग यूआरएल
लंबी आईडी लंबी आईडी

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

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