Stile del codice Java AOSP per i collaboratori

Gli stili di codice in questa pagina sono regole rigide per integrare il codice Java Android Open Source Project (AOSP). Contributi alla piattaforma Android che non rispettano queste regole generalmente non sono accettati. Me riconoscere che non tutto il codice esistente segue queste regole, ma ci aspettiamo che nuovo codice per essere conforme. Leggi la sezione Codificare con rispetto per esempi di terminologia da usare ed evitare per un ecosistema più inclusivo.

Sii costante

Una delle regole più semplici è la costanza. Se devi modificare il codice, prendine minuti per esaminare il codice circostante e determinarne lo stile. Se questo usa degli spazi attorno alle clausole if. Se il codice commenti hanno piccole scatole di stelle intorno a loro, fai in modo che i tuoi commenti anche delle scatole di stelle intorno a loro.

Lo scopo delle linee guida di stile è avere un vocabolario comune di di programmazione, in modo che i lettori possano concentrarsi su ciò che dici, anziché su come lo dici. Qui vengono presentate le regole di stile globali, in modo che il vocabolario, ma anche lo stile locale è importante. Se il codice che aggiungi a un file ha un aspetto nettamente diverso dal codice esistente intorno al file, distrae il ritmo dei lettori quando lo leggono. Prova a evitare questo problema.

Regole del linguaggio Java

Android segue le convenzioni di programmazione Java standard con le regole aggiuntive descritti di seguito.

Non ignorare le eccezioni

Potresti avere la tentazione di scrivere codice che ignora un'eccezione, ad esempio:

  void setServerPort(String value) {
      try {
          serverPort = Integer.parseInt(value);
      } catch (NumberFormatException e) { }
  }

Non farlo. Anche se puoi pensare che il tuo codice non sia mai condizione di errore o che non è importante gestirla, ignorando questo tipo un'eccezione crea dei mini nel tuo codice per permettere a qualcun altro si attivino per un giorno. Devi gestire ogni eccezione nel codice in un basata sul principio; La gestione specifica varia a seconda del caso.

"Ogni volta che qualcuno ha una clausola di intercettazione vuota, dovrebbe avere un in tutta la casa. Ci sono sicuramente momenti in cui cosa da fare, ma almeno devi pensarci. In Java non puoi scappa da quella sensazione inquietante." - Giacomo Gosling

Le alternative accettabili (in ordine di preferenza) sono:

  • Distribuisci l'eccezione al chiamante del tuo metodo.
      void setServerPort(String value) throws NumberFormatException {
          serverPort = Integer.parseInt(value);
      }
    
  • Genera una nuova eccezione appropriata per il tuo livello di astrazione.
      void setServerPort(String value) throws ConfigurationException {
        try {
            serverPort = Integer.parseInt(value);
        } catch (NumberFormatException e) {
            throw new ConfigurationException("Port " + value + " is not valid.");
        }
      }
    
  • Gestisci l'errore con cautela e sostituisci un valore appropriato nel campo Blocco 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
        }
      }
    
  • Individua l'eccezione e genera una nuova istanza di RuntimeException. È pericoloso, quindi fallo solo se hai la certezza che si verifica un errore, la cosa giusta da fare è arresto anomalo.
      /** 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);
        }
      }
    
  • Come ultima risorsa, se sei sicuro che ignorare l'eccezione è appropriato, puoi ignorarlo, ma devi anche commentare il motivo con un buon motivo.
    /** 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.
        }
    }
    

Non rilevare eccezioni generiche

La pigrizia quando si accorge delle eccezioni e lo fa ad esempio:

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

Non farlo. In quasi tutti i casi, non è appropriato individuare Exception o Throwable (preferibilmente non Throwable perché include Error eccezioni). È pericoloso perché significa che le eccezioni mai previsto (incluse le eccezioni di runtime come ClassCastException) essere intrappolati nella gestione degli errori a livello di app. Oscura l'errore- gestire le proprietà del codice, ovvero se qualcuno aggiunge un nuovo tipo nel codice che stai chiamando, il compilatore non segnalerà che devi gestire l'errore in modo diverso. Nella maggior parte dei casi non devono gestire diversi tipi di eccezioni allo stesso modo.

La rara eccezione a questa regola è costituita dal codice di test e dal codice di primo livello in cui rilevare tutti i tipi di errori (per evitare che vengano visualizzati in una UI o mantenere in esecuzione un job batch). In questi casi, potresti rilevare il valore generico Exception (o Throwable) e gestire l'errore in modo appropriato. Rifletti attentamente prima di farlo e inserisci dei commenti spiegando perché è sicura in questo contesto.

Alternative al rilevamento di eccezioni generiche:

  • Individua ogni eccezione separatamente come parte di un blocco multi-catch, ad esempio:
    try {
        ...
    } catch (ClassNotFoundException | NoSuchMethodException e) {
        ...
    }
  • Esegui il refactoring del codice per una gestione degli errori più granulare, con più blocchi di prova. Suddividi l'IO dall'analisi e gestisci gli errori separatamente in ogni caso.
  • Esegui di nuovo l'eccezione. Molte volte non è necessario cogliere a questo livello, lascia che sia il metodo a generarla.

Ricorda che ci sono le eccezioni. Quando il compilatore si lamenta del fatto non rilevare un'eccezione, non aggrottare le sopracciglia. Sorridi! Il compilatore ce l'ha appena fatta è più facile individuare i problemi di runtime nel codice.

Non utilizzare i finalizzatori

I finalizzatori sono un modo per eseguire un blocco di codice quando un oggetto garbage collection. Anche se i finalizzatori possono essere utili per la pulizia, (in particolare delle risorse esterne), non vi è alcuna garanzia in merito a quando viene chiamato (o anche se lo farà del tutto).

Android non utilizza i finalizzatori. Nella maggior parte dei casi, puoi utilizzare una buona gestione delle eccezioni. Se hai assolutamente bisogno di un finalizzatore, definisci un metodo close() (o simile) e documenta esattamente quando deve essere chiamato (vedi InputStream per un esempio). In questo caso, è appropriato ma non è necessario stampare un breve messaggio di log dal finale, purché non sia previsto che i log vengano inondati.

Qualifica completamente le importazioni

Quando vuoi utilizzare la classe Bar del pacchetto foo, puoi scegliere tra due opzioni possibili modi per importarlo:

  • import foo.*;

    Riduce potenzialmente il numero di istruzioni di importazione.

  • import foo.Bar;

    Rende ovvio quali classi vengono utilizzate e il codice è più leggibile per i manutentori.

Usa import foo.Bar; per importare tutto il codice Android. Un viene fatta un'eccezione esplicita per le librerie standard Java (java.util.*, java.io.* e così via) e il codice del test delle unità (junit.framework.*).

Regole della libreria Java

Esistono convenzioni per l'utilizzo delle librerie e degli strumenti Java di Android. Nella alcuni casi, la convenzione è cambiata in modi importanti e il codice più vecchio potrebbero utilizzare pattern o librerie deprecati. Lavorando con questo codice, puoi continuare con lo stile esistente. Durante la creazione di nuovi componenti ma non usare mai librerie deprecate.

Regole di stile Java

Utilizza commenti standard Javadoc

Ogni file deve includere una dichiarazione sul copyright nella parte superiore, seguita da istruzioni per pacchetti e import (ogni blocco è separato da una riga vuota) e infine la dichiarazione di classe o dell'interfaccia. Nei commenti Javadoc, descrivere cosa fa la classe o l'interfaccia.

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

Ogni classe e metodo pubblico non banale che scrivi deve contenere un commento Javadoc con almeno una frase che descrive ciò che la classe . Questa frase deve iniziare con una terza persona verbo descrittivo.

Esempi

/** Returns the correctly rounded positive square root of a double value. */

static double sqrt(double a) {
    ...
}

oppure

/**
 * Constructs a new String by converting the specified array of
 * bytes using the platform's default character encoding.
 */
public String(byte[] bytes) {
    ...
}

Non è necessario scrivere Javadoc per metodi get e set banali come setFoo() se tutto il codice Javadoc dice "set Foo". Se il metodo esegue operazioni più complesse, come l'applicazione forzata di un vincolo o ha un importante effetto collaterale), è necessario documentarlo. In caso contrario è ovvio che la proprietà "Foo" significa che dovresti documentarlo.

Ogni metodo che scrivi, pubblico o di altro tipo, trarrebbe vantaggio da Javadoc. I metodi pubblici fanno parte di un'API e pertanto richiedono Javadoc. Android non applica uno stile specifico per la scrittura di Javadoc commenti, ma devi seguire le istruzioni riportate in Come scrivere commenti dei documenti per lo strumento Javadoc.

Scrivere metodi brevi

Se possibile, utilizza metodi limitati e mirati. Riconosciamo che metodi sono talvolta appropriati, quindi non viene imposto alcun limite sul metodo lunghezza. Se un metodo supera le 40 righe circa, valuta se può possono essere suddivisi senza danneggiare la struttura del programma.

Definisci i campi in posizioni standard

Definisci i campi all'inizio del file o immediatamente prima del che li utilizzano.

Limita ambito variabile

Riduci al minimo l'ambito delle variabili locali. Questo aumenta la leggibilità e la manutenibilità del codice e riduce probabilità di errore. Dichiara ogni variabile nel che racchiude tutti gli usi della variabile.

Dichiara le variabili locali nel momento in cui vengono utilizzate per la prima volta. Quasi ogni dichiarazione di variabile locale dovrebbe contenere un inizializzatore. Se non disponi ancora di informazioni sufficienti per inizializzare una variabile è opportuno posticipare la dichiarazione finché non lo farai.

Fanno eccezione le istruzioni prova-catch. Se una variabile viene inizializzata con il valore restituito di un metodo che genera un'eccezione selezionata, deve essere inizializzato in un blocco di prova. Se il valore deve essere utilizzato al di fuori del campo test, deve essere dichiarato prima del blocco test, dove non può ancora essere inizializzato in modo significativo:

// 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));

Tuttavia, si può anche evitare questo caso integrando la richiesta di prova bloccare in un metodo:

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

Dichiarare le variabili di loop nell'istruzione for stessa a meno che c'è un valido motivo per farlo:

for (int i = 0; i < n; i++) {
    doSomething(i);
}

e

for (Iterator i = c.iterator(); i.hasNext(); ) {
    doSomethingElse(i.next());
}

Ordina istruzioni per l'importazione

L'ordine delle istruzioni di importazione è il seguente:

  1. Importazioni Android
  2. Importazioni da terze parti (com, junit, net org)
  3. java e javax

Per far corrispondere esattamente le impostazioni dell'IDE, le importazioni devono essere:

  • Ordine alfabetico all'interno di ogni raggruppamento, con lettere maiuscole prima della lettera minuscola lettere maiuscole e minuscole (ad esempio, Z prima della a)
  • Separati da una linea vuota tra ciascun raggruppamento principale (android, com, junit, net, org, java javax)

In origine, non era previsto alcun requisito di stile nell'ordine, il che significa che gli IDE o cambiavano sempre l'ordine oppure gli sviluppatori IDE dovevano disattivare le funzioni automatiche di gestione dell'importazione e mantenere manualmente le importazioni. Questo è stato ritenuto pessimo. Quando è stato chiesto lo stile Java, gli stili preferiti cambiavano enormemente; si pensava ad Android che doveva è sufficiente "scegliere un ordine e sii coerente". Quindi abbiamo scelto uno stile, ha aggiornato la guida di stile e ha fatto sì che gli IDE la rispettassero. Ci aspettiamo che Gli utenti IDE lavorano al codice, le importazioni in tutti i pacchetti corrisponderanno a questo senza ulteriori sforzi ingegneristici.

Abbiamo scelto questo stile in modo che:

  • Le importazioni che le persone vogliono esaminare per prime tendono a trovarsi nelle prime posizioni (android)
  • Le importazioni che le persone vogliono controllare tendono a trovarsi nelle ultime 24 ore (java)
  • Gli esseri umani possono seguire facilmente lo stile.
  • Gli IDE possono seguire lo stile.

Colloca le importazioni statiche sopra tutte le altre, ordinate come segue: importazioni standard.

Usa gli spazi per il rientro

Utilizziamo quattro (4) rientri per i blocchi e mai le tabulazioni. In caso di dubbi, coerente con il codice circostante.

Utilizziamo otto (8) rientri di spazio per i caratteri a capo, incluse le chiamate di funzione e le assegnazioni.

Consigliato

Instrument i =
        someLongExpression(that, wouldNotFit, on, one, line);

Sconsigliato

Instrument i =
    someLongExpression(that, wouldNotFit, on, one, line);

Segui le convenzioni di denominazione dei campi

  • I nomi dei campi non pubblici e non statici iniziano con m.
  • I nomi dei campi statici iniziano con s.
  • Gli altri campi iniziano con una lettera minuscola.
  • I campi finali statici (costanti, profondamente immutabili) sono ALL_CAPS_WITH_UNDERSCORES.

Ad esempio:

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

Usa lo stile della parentesi graffa standard

Inserisci le parentesi graffe nella stessa riga del codice che lo precede, non in una riga separata:

class MyClass {
    int func() {
        if (something) {
            // ...
        } else if (somethingElse) {
            // ...
        } else {
            // ...
        }
    }
}

Le affermazioni per un condizionale sono obbligatorie. Eccezione: se l'intero condizionale (la condizione e il corpo) rientra in una sola riga, possono (ma non sono obbligati a) mettere tutto su un'unica riga. Ad esempio, questo accettabile:

if (condition) {
    body();
}

ed è accettabile:

if (condition) body();

ma non è accettabile:

if (condition)
    body();  // bad!

Limita lunghezza linea

Ogni riga di testo del codice deve contenere al massimo 100 caratteri. Questa regola è circoscritta a molti dibattiti, ma la decisione rimane il limite massimo di 100 caratteri con i seguenti eccezioni:

  • Se una riga di commento contiene un comando di esempio o un URL letterale più lungo con più di 100 caratteri, la riga può contenere più di 100 caratteri per taglia e incolla con facilità.
  • Le righe di importazione possono superare il limite perché le persone raramente le vedono (questo semplifica anche la scrittura sullo strumento).

Utilizza annotazioni Java standard

Le annotazioni devono precedere altri modificatori per la stessa lingua . È possibile inserire semplici annotazioni degli indicatori (ad es. @Override) nella nella stessa riga con l'elemento language. Se ci sono più annotazioni, o con parametri, elencali una per riga in ordine alfabetico.

Pratiche standard Android per le tre annotazioni predefinite in Java sono:

  • Utilizza l'annotazione @Deprecated ogni volta che si sconsiglia l'utilizzo dell'elemento annotato. Se utilizzi l'annotazione @Deprecated, devi avere anche un valore @deprecated tag Javadoc e dovrebbe nominare un'implementazione alternativa. Inoltre, ricorda che un metodo @Deprecated dovrebbe continuare a funzionare. Se vedi il codice precedente con un tag Javadoc @deprecated, aggiungi il metodo Annotazione @Deprecated.
  • Utilizza l'annotazione @Override ogni volta un metodo sostituisce la dichiarazione o l'implementazione da la superclasse del progetto. Ad esempio, se utilizzi il tag Javadoc @inheritdocs e derivare da una classe (non un'interfaccia), devi anche annotare Il metodo sostituisce il metodo della classe padre.
  • Utilizza l'annotazione @SuppressWarnings solo nei casi in cui non sia possibile per eliminare un avviso. Se un avviso supera questo messaggio elimina" test, l'annotazione @SuppressWarnings deve essere utilizzati, per garantire che tutti gli avvisi riflettano i problemi effettivi nel le API nel tuo codice.

    Quando è necessaria un'annotazione @SuppressWarnings, deve essere preceduto da un commento TODO che spiega "impossibile elimina" . Normalmente identifica una classe incriminata con un'interfaccia scomoda. Ad esempio:

    // TODO: The third-party class com.third.useful.Utility.rotate() needs generics
    @SuppressWarnings("generic-cast")
    List<String> blix = Utility.rotate(blax);
    

    Quando è necessaria un'annotazione @SuppressWarnings, esegui il refactoring del codice per isolare gli elementi software in cui l'annotazione .

Tratta gli acronimi come parole

Tratta gli acronimi e le abbreviazioni come parole per denominare variabili, metodi, e classi per rendere i nomi più leggibili:

Buono Scadente
XmlHttpRequest XMLHTTPRequest
ID cliente getCustomerID
classe HTML class HTML
URL stringa URL stringa
ID lungo ID lungo

Sia il codice JDK sia quello di Android non sono coerenti è praticamente impossibile essere coerenti con codice circostante. Per questo motivo, considera sempre gli acronimi come parole.

Utilizza i commenti TODO

Utilizza i commenti TODO per il codice temporaneo, una soluzione a breve termine oppure abbastanza buono, ma non perfetto. Questi commenti devono includere la stringa TODO in tutti maiuscole, seguite dai due punti:

// TODO: Remove this code after the UrlTable2 has been checked in.

e

// TODO: Change this to use a flag instead of a constant.

Se il formato TODO è "In una data futura, fai qualcosa" assicurati che di includere una data specifica ("Correzione entro novembre 2005") oppure per un evento specifico ("Rimuovi questo codice dopo tutti i mixer di produzione) per capire il protocollo V7.").

Registra con parsimonia

Sebbene il logging sia necessario, ha un impatto negativo prestazioni e perde la sua utilità se non mantenuto ragionevolmente consecutiva. Le strutture di registrazione offrono cinque diversi livelli di registrazione delle aree di lavorazione:

  • ERROR: da usare se si è verificata un'azione irreversibile, ovvero qualcosa avrà conseguenze visibili all'utente e non sarà recuperabile senza eliminare alcuni dati, disinstallare le app cancellare le partizioni dei dati o eseguire di nuovo il flash dell'intero dispositivo (o peggio ancora). Questo livello viene sempre registrato. Problemi che giustificano alcune attività di logging Il livello ERROR è adatto per essere segnalato a un di raccolta delle statistiche.
  • WARNING: da utilizzare quando si tratta di qualcosa di serio e inaspettato successo, qualcosa che avrà conseguenze visibili all'utente, sia recuperabile senza perdita di dati eseguendo alcune un'azione esplicita, ad esempio attendere o riavviare un'app a riscaricare una nuova versione di un'app o al riavvio dispositivo. Questo livello viene sempre registrato. Problemi che giustificano il logging a livello di WARNING potrebbero essere presi in considerazione anche per i report di raccolta delle statistiche.
  • INFORMATIVE: usalo per segnalare che qualcosa di interessante cioè quando viene rilevata una situazione che probabilmente avere un impatto diffuso, anche se non è necessariamente un errore. Un tale deve essere registrata solo da un modulo che ritiene che sia il più autorevole nel dominio (per evitare duplicati il logging da parte di componenti non autorevoli). Questo livello viene sempre registrato.
  • DEBUG: utilizza questa opzione per annotare ulteriormente cosa succede sul un dispositivo pertinente per l'analisi e il debug i comportamenti dei modelli, Registra solo ciò che è necessario per raccogliere abbastanza informazioni su cosa sta succedendo con il tuo componente. Se il debug i log sono in cima ai log, allora è necessario usare i log log.

    Questo livello viene registrato anche nelle build della release ed è obbligatorio essere circondato da un blocco if (LOCAL_LOG) o if LOCAL_LOGD), dove LOCAL_LOG[D] è definito nella classe o nel sottocomponente, in modo che esista la possibilità per disattivare tutti questi tipi di logging. Pertanto, non deve esserci logica attiva in un blocco if (LOCAL_LOG). Tutte le funzioni per creare stringhe il log deve essere posizionato all'interno Blocco if (LOCAL_LOG). Non eseguire il refactoring della chiamata di logging in una chiamata di metodo se farà sì che la creazione di stringhe che avvenga al di fuori Blocco if (LOCAL_LOG).

    C'è del codice ancora con la dicitura if (localLOGV). Questo è considerata accettabile, anche se il nome non è standard.

  • VERBOSE: da utilizzare per tutto il resto. Questo livello è disponibile solo registrato sulle build di debug e deve essere circondato da Blocco if (LOCAL_LOGV) (o equivalente) in modo che possa essere compilate per impostazione predefinita. Qualsiasi struttura di stringhe viene eliminata di release e deve essere presente all'interno Blocco if (LOCAL_LOGV).

Note

  • All'interno di un determinato modulo, diverso da quello a livello di VERBOSE, si è verificato un errore devono essere segnalati una sola volta, se possibile. All'interno di una singola catena all'interno di un modulo, solo la funzione più interna dovrebbe restituiscono l'errore e i chiamanti nello stesso modulo devono aggiungere dei log, se questo aiuta notevolmente a isolare il problema.
  • In una catena di moduli, diversa da quella a livello di VERBOSE, quando una rileva dati non validi provenienti da un modulo di livello superiore. modulo di livello inferiore, il modulo di livello inferiore dovrebbe registrare questa situazione solo nel DEBUG e solo se quest'ultimo fornisce informazioni che non sono altrimenti disponibili per il chiamante. Nello specifico, non è necessario registrare le situazioni in cui viene generata un'eccezione (l'eccezione dovrebbe contengono tutte le informazioni pertinenti) o se le uniche informazioni registrato è contenuto in un codice di errore. In particolare sono importanti nell'interazione tra framework e app, e condizioni causate da app di terze parti che sono gestito dal framework non deve attivare un logging superiore al Livello DEBUG. Le uniche situazioni che dovrebbero attivare il logging al A livello INFORMATIVE o superiore si intende quando un modulo o un'app rileva un errore al suo livello o proveniente da un livello inferiore.
  • Quando è probabile che una condizione che normalmente giustifica il logging sia si verificano molte volte, è consigliabile implementare alcune di limitazione della frequenza di traffico per evitare l'overflow dei log con copie duplicate delle stesse informazioni (o molto simili).
  • Le perdite di connettività di rete sono considerate comuni e sono previsto e non deve essere registrato senza costi. Perdita di rete la connettività con conseguenze all'interno di un'app deve essere registrata il livello DEBUG o VERBOSE (a seconda che il sono abbastanza gravi e inaspettate da essere registrate in una release build).
  • Avere un file system completo in un file system accessibile o su per conto di app di terze parti non devono essere registrati a livello superiore a INFORMATIVO.
  • Dati non validi provenienti da una fonte non attendibile (compreso qualsiasi file su spazio di archiviazione condiviso o dati che provengono da una rete connessione) è considerata prevista e non deve attivare alcuna a un livello superiore a DEBUG quando viene rilevato non valido (anche in questo caso il logging dovrebbe essere il più limitato possibile).
  • Se utilizzato in oggetti String, l'operatore + implicitamente crea un'istanza StringBuilder con il valore predefinito dimensione del buffer (16 caratteri) e potenzialmente altro String temporaneo di oggetti strutturati. Quindi creare esplicitamente StringBuilder oggetti non è rispetto all'utilizzo dell'operatore + predefinito (e può essere molto più efficiente). Ricorda che il codice che chiama Log.v() viene compilato ed eseguito sulle build di release, inclusa la creazione delle stringhe, anche se i log non vengono letti.
  • Qualsiasi registrazione destinata a essere letta da altre persone e disponibili nelle build di release devono essere concisi senza essere criptici, e devono essere comprensibili. Sono inclusi tutti i log fino al livello DEBUG.
  • Se possibile, continua a registrare i dati su un'unica riga. Le righe possono contenere fino a 80 o 100 caratteri accettabile. Evita lunghezze superiori a 130 o 160 caratteri. (inclusa la lunghezza del tag), se possibile.
  • Se il logging ha esito positivo, non utilizzarlo mai a livelli superiori. di VERBOSE.
  • Se utilizzi il logging temporaneo per diagnosticare un problema difficile da risolvere riprodurlo, mantienilo al livello DEBUG o VERBOSE e racchiudilo tra blocchi if che consentono la disattivazione in durante la compilazione.
  • Fai attenzione alle fughe di sicurezza tramite il log. Evita il logging privato informazioni. In particolare, evita di inserire informazioni sui contenuti protetti. Ciò è particolarmente importante quando scrivere il codice di un framework in quanto non è facile sapere in anticipo cosa e non saranno informazioni private o contenuti protetti.
  • Non usare mai System.out.println() (o printf() per codice nativo). System.out e System.err ricevono sono reindirizzati a /dev/null, pertanto i tuoi estratti conto di stampa non contengono effetti visibili. Tuttavia, tutte le fasi di creazione di stringhe queste chiamate vengono comunque eseguite.
  • La regola d'oro del logging è che i log potrebbero non spinge inutilmente altri log fuori dal buffer, proprio come gli altri e non distribuirla.

Regole di stile Javatest

Segui le convenzioni di denominazione dei metodi di test e utilizza un trattino basso per separare a ciò che viene testato dal caso specifico in fase di test. Questo stile rende è più facile vedere quali casi vengono testati. Ad esempio:

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