AOSP Java Code Style for Contributors

Gli stili di codice in questa pagina sono regole severe per contribuire al codice Java all’Android Open Source Project (AOSP). I contributi alla piattaforma Android che non aderiscono a queste regole generalmente non sono accettati. Riconosciamo che non tutto il codice esistente segue queste regole, ma ci aspettiamo che tutto il nuovo codice sia conforme. Vedi Coding with Respect per esempi di terminologia da usare ed evitare per un ecosistema più inclusivo.

Be consistent

Una delle regole più semplici è ESSERE CONSISTENTI. Se stai modificando del codice, prenditi qualche minuto per guardare il codice circostante e determinare il suo stile. Se quel codice usa spazi intorno alle clausole if, dovresti farlo anche tu. Se i commenti al codice hanno piccole scatole di stelle intorno a loro, fate che anche i vostri commenti abbiano piccole scatole di stelle intorno a loro.

Lo scopo di avere delle linee guida di stile è quello di avere un vocabolario comune di codifica, in modo che i lettori possano concentrarsi su quello che state dicendo, piuttosto che su come lo state dicendo. Qui presentiamo regole di stile globali in modo che conosciate il vocabolario, ma anche lo stile locale è importante. Se il codice che aggiungi ad un file sembra drasticamente diverso dal codice esistente intorno ad esso, getta i lettori fuori ritmo quando lo leggono. Cercate di evitarlo.

Regole del linguaggio Java

Android segue le convenzioni standard di codifica Java con le regole aggiuntive descritte sotto.

Non ignorare le eccezioni

Può essere allettante scrivere codice che ignora un’eccezione, come ad esempio:

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

Non fatelo. Sebbene possiate pensare che il vostro codice non incontrerà mai questa condizione di errore o che non sia importante gestirla, ignorare questo tipo di eccezione crea delle miniere nel vostro codice per qualcun altro che un giorno si attiverà. Dovete gestire tutte le eccezioni nel vostro codice in un modo di principio; la gestione specifica varia a seconda del caso.

“Ogni volta che qualcuno ha una clausola catch vuota dovrebbe avere una sensazione inquietante. Ci sono sicuramente delle volte in cui è effettivamente la cosa giusta da fare, ma almeno ci si deve pensare. In Java non si può sfuggire alla sensazione raccapricciante”. – James Gosling

Le alternative accettabili (in ordine di preferenza) sono:

  • Lancia l’eccezione fino al chiamante del tuo metodo.
     void setServerPort(String value) throws NumberFormatException { serverPort = Integer.parseInt(value); }
  • Lancia una nuova eccezione che sia appropriata al 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."); } }
  • Gestite l’errore con grazia e sostituite un valore appropriato nel 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 } }
  • Catturate l’eccezione e lanciate una nuova istanza di RuntimeException. Questo è pericoloso, quindi fatelo solo se siete sicuri che se questo errore si verifica, la cosa appropriata da fare è il crash.
     /** 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 siete sicuri che ignorare l’eccezione è appropriato allora potete ignorarla, ma dovete anche commentare il perché con una buona ragione.
    /** 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 catturare eccezioni generiche

Si può essere tentati di essere pigri quando si catturano le eccezioni e fare qualcosa del genere:

 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 fatelo. In quasi tutti i casi, è inappropriato catturare generici Exception o Throwable (preferibilmente non Throwable perché include Error eccezioni). È pericoloso perché significa che le eccezioni che non ci si aspettava (comprese le eccezioni di runtime come ClassCastException) vengono catturate nella gestione degli errori a livello di app. Oscura le proprietà di gestione degli errori del vostro codice, il che significa che se qualcuno aggiunge un nuovo tipo di eccezione nel codice che state chiamando, il compilatore non vi farà notare che avete bisogno di gestire l’errore in modo diverso. Nella maggior parte dei casi non dovreste gestire diversi tipi di eccezioni allo stesso modo.

La rara eccezione a questa regola è il codice di test e il codice di alto livello dove si vogliono catturare tutti i tipi di errori (per evitare che appaiano in un’interfaccia utente, o per mantenere un lavoro batch in esecuzione). In questi casi, si può catturare il generico Exception (o Throwable) e gestire l’errore in modo appropriato. Pensateci bene prima di farlo, però, e inserite dei commenti che spieghino perché è sicuro in questo contesto.

Alternative alla cattura di eccezioni generiche:

  • Cattura ogni eccezione separatamente come parte di un blocco multi-catch, per esempio:
    try { ...} catch (ClassNotFoundException | NoSuchMethodException e) { ...}
  • Rifattorizza il tuo codice per avere una gestione degli errori più fine, con più blocchi try. Dividete l’IO dall’analisi, e gestite gli errori separatamente in ogni caso.
  • Lancia l’eccezione. Molte volte non c’è bisogno di catturare l’eccezione a questo livello, basta lasciare che il metodo la lanci.

Ricordate che le eccezioni sono vostre amiche! Quando il compilatore si lamenta che non state catturando un’eccezione, non aggrottate la fronte. Sorridete! Il compilatore ha appena reso più facile per voi catturare i problemi di runtime nel vostro codice.

Non usare i finalizzatori

I finalizzatori sono un modo per avere un pezzo di codice eseguito quando un oggetto viene smaltito. Mentre i finalizzatori possono essere utili per la pulizia (in particolare di risorse esterne), non ci sono garanzie su quando un finalizzatore sarà chiamato (o addirittura che sarà chiamato del tutto).

Android non usa i finalizzatori. Nella maggior parte dei casi, potete invece usare una buona gestione delle eccezioni. If you absolutely need a finalizer, define a close() method (or the like) and document exactly when that method needs to be called (see InputStream for an example). In this case, it’s appropriate but not required to print a short log message from the finalizer, as long as it’s not expected to flood the logs.

Fully qualify imports

When you want to use class Bar from package foo, there are two possible ways to import it:

  • import foo.*;

    Potentially reduces the number of import statements.

  • import foo.Bar;

    Makes it obvious what classes are used and the code is more readable for maintainers.

Use import foo.Bar; for importing all Android code. An explicit exception is made for Java standard libraries (java.util.*java.io.*, etc.) and unit test code (junit.framework.*).

Regole della libreria Java

Ci sono delle convenzioni per l’uso delle librerie e degli strumenti Java di Android. In alcuni casi, la convenzione è cambiata in modi importanti e il codice più vecchio potrebbe usare uno schema o una libreria deprecata. Quando si lavora con tale codice, va bene continuare lo stile esistente. Tuttavia, quando si creano nuovi componenti, non usare mai librerie deprecate.

Regole di stile Java

Ogni file dovrebbe avere una dichiarazione di copyright all’inizio, seguita da dichiarazioni di package e import (ogni blocco separato da una riga vuota), e infine la dichiarazione di classe o interfaccia. Nei commenti Javadoc, descrivi cosa fa la classe o l’interfaccia.

/* * Copyright 2020 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 si scrive deve contenere un commento Javadoc con almeno una frase che descriva cosa fa la classe o il metodo. Questa frase dovrebbe iniziare con un verbo descrittivo in terza persona.

Esempi

/** Returns the correctly rounded positive square root of a double value. */static double sqrt(double a) { ...}

o

/** * 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 banali metodi get e set come setFoo() se tutto quello che il vostro Javadoc direbbe è “sets Foo”. Se il metodo fa qualcosa di più complesso (come far rispettare un vincolo o avere un importante effetto collaterale), allora dovete documentarlo. Se non è ovvio cosa significa la proprietà “Foo”, dovreste documentarlo.

Ogni metodo che scrivete, pubblico o meno, beneficerebbe di Javadoc. I metodi pubblici sono parte di un’API e quindi richiedono Javadoc. Android non impone uno stile specifico per scrivere i commenti Javadoc, ma dovreste seguire le istruzioni in Come scrivere i commenti per lo strumento Javadoc.

Scrivi metodi brevi

Quando possibile, mantieni i metodi piccoli e mirati. Riconosciamo che i metodi lunghi a volte sono appropriati, quindi non c’è un limite rigido alla lunghezza dei metodi. Se un metodo supera le 40 righe circa, pensate se può essere spezzato senza danneggiare la struttura del programma.

Definisci i campi in posti standard

Definisci i campi o all’inizio del file o immediatamente prima dei metodi che li usano.

Limitare lo scopo delle variabili

Mantenere lo scopo delle variabili locali al minimo. Questo aumenta la leggibilità e la manutenibilità del vostro codice e riduce la probabilità di errore. Dichiarare ogni variabile nel blocco più interno che racchiude tutti gli usi della variabile.

Dichiarare le variabili locali nel punto in cui vengono usate per la prima volta. Quasi ogni dichiarazione di variabile locale dovrebbe contenere un inizializzatore. Se non avete ancora abbastanza informazioni per inizializzare una variabile in modo sensato, rimandate la dichiarazione fino a quando non l’avrete fatto.

L’eccezione sono le dichiarazioni try-catch. Se una variabile viene inizializzata con il valore di ritorno di un metodo che lancia un’eccezione controllata, deve essere inizializzata all’interno di un blocco try. If the value must be used outside of the try block, then it must be declared before the try block, where it can’t yet be sensibly initialized:

// Instantiate class cl, which represents some sort of SetSet 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 sets.addAll(Arrays.asList(args));

However, you can even avoid this case by encapsulating the try-catch block in a method:

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 setSet s = createSet(cl);s.addAll(Arrays.asList(args));

Declare loop variables in the for statement itself unless there’s a compelling reason to do otherwise:

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

and

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

Order import statements

The ordering of import statements is:

  1. Android imports
  2. Imports from third parties (comjunitnetorg)
  3. java and javax

To exactly match the IDE settings, the imports should be:

  • Alfabetico all’interno di ogni raggruppamento, con le lettere maiuscole prima delle lettere minuscole (per esempio, la Z prima della a)
  • Separati da una linea bianca tra ogni raggruppamento principale (androidcomjunitnetorgjavajavax)

Originariamente, non c’erano requisiti di stile sull’ordinamento, il che significa che gli IDE o cambiavano sempre l’ordinamento o gli sviluppatori IDE dovevano disabilitare le funzioni di gestione automatica delle importazioni e mantenere manualmente le importazioni. Questo era considerato un male. Quando è stato chiesto lo stile Java, gli stili preferiti variavano selvaggiamente e si è arrivati alla necessità di Android di “scegliere un ordinamento ed essere coerenti”. Così abbiamo scelto uno stile, aggiornato la guida di stile, e fatto in modo che gli IDE obbedissero. Ci aspettiamo che, man mano che gli utenti dell’IDE lavorano sul codice, le importazioni in tutti i pacchetti corrispondano a questo modello senza sforzi ingegneristici aggiuntivi.

We chose this style such that:

  • The imports that people want to look at first tend to be at the top (android).
  • The imports that people want to look at least tend to be at the bottom (java).
  • Humans can easily follow the style.
  • IDEs can follow the style.

Put static imports above all the other imports ordered the same way as regular imports.

Use spaces for indentation

We use four (4) space indents for blocks and never tabs. When in doubt, be consistent with the surrounding code.

We use eight (8) space indents for line wraps, including function calls and assignments.

Recommended

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

Not recommended

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

Follow field naming conventions

  • Non-public, non-static field names start with m.
  • Static field names start with s.
  • Other fields start with a lower case letter.
  • Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.

For example:

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

Use standard brace style

Put braces on the same line as the code before them, not on their own line:

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

We require braces around the statements for a conditional. Exception: If the entire conditional (the condition and the body) fit on one line, you may (but are not obligated to) put it all on one line. For example, this is acceptable:

if (condition) { body();}

and this is acceptable:

if (condition) body();

but this is not acceptable:

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

Limit line length

Each line of text in your code should be at most 100 characters long. While much discussion has surrounded this rule, the decision remains that 100 characters is the maximum with the following exceptions:

  • Se una riga di commento contiene un comando di esempio o un URL letterale più lungo di 100 caratteri, quella riga può essere più lunga di 100 caratteri per facilitare il taglia e incolla.
  • Le linee di importazione possono andare oltre il limite perché gli umani le vedono raramente (questo semplifica anche la scrittura degli strumenti).

Utilizzare annotazioni Java standard

Le annotazioni dovrebbero precedere altri modificatori per lo stesso elemento linguistico. Le annotazioni marker semplici (per esempio, @Override) possono essere elencate sulla stessa linea con l’elemento di lingua. Se ci sono più annotazioni, o annotazioni parametrizzate, elencale una per riga in ordine alfabetico.

Le pratiche standard di Android per le tre annotazioni predefinite in Java sono:

  • Usa l’annotazione @Deprecated ogni volta che l’uso dell’elemento annotato è scoraggiato. Se usate l’annotazione @Deprecated, dovete anche avere un tag @deprecated Javadoc e dovrebbe nominare un’implementazione alternativa. Inoltre, ricordate che un metodo @Deprecated dovrebbe ancora funzionare. Se vedi del vecchio codice che ha un tag @deprecated Javadoc, aggiungi l’annotazione @Deprecated.
  • Usate l’annotazione @Override ogni volta che un metodo sovrascrive la dichiarazione o l’implementazione di una superclasse. Per esempio, se usate il tag @inheritdocs Javadoc, e derivate da una classe (non un’interfaccia), dovete anche annotare che il metodo sovrascrive il metodo della classe madre.
  • Usate l’annotazione @SuppressWarnings solo in circostanze in cui è impossibile eliminare un avvertimento. If a warning passes this “impossible to eliminate” test, the @SuppressWarnings annotation must be used, to ensure that all warnings reflect actual problems in the code.

    When a @SuppressWarnings annotation is necessary, it must be prefixed with a TODO comment that explains the “impossible to eliminate” condition. This normally identifies an offending class that has an awkward interface. Per esempio:

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

    When a @SuppressWarnings annotation is required, refactor the code to isolate the software elements where the annotation applies.

Treat acronyms as words

Treat acronyms and abbreviations as words in naming variables, methods, and classes to make names more readable:

Good Bad
XmlHttpRequest XMLHTTPRequest
getCustomerId getCustomerID
class Html class HTML
String url String URL
long id long ID

As both the JDK and the Android code bases are inconsistent around acronyms, it’s virtually impossible to be consistent with the surrounding code. Therefore, always treat acronyms as words.

Use TODO comments for code that is temporary, a short-term solution, or good enough but not perfect. These comments should include the string TODO in all caps, followed by a colon:

// 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 vostro TODO è della forma “In una data futura fate qualcosa” assicuratevi di includere una data specifica (“Fix by November 2005”) o un evento specifico (“Remove this code after all production mixers understand protocol V7.”).

Log con parsimonia

Mentre il logging è necessario, ha un impatto negativo sulle prestazioni e perde la sua utilità se non viene mantenuto ragionevolmente conciso. Le strutture di log forniscono cinque diversi livelli di log:

  • ERROR: Da usare quando è successo qualcosa di fatale, cioè qualcosa che avrà conseguenze visibili all’utente e che non sarà recuperabile senza cancellare alcuni dati, disinstallare le applicazioni, cancellare le partizioni dei dati, o riflashare l’intero dispositivo (o peggio). Questo livello viene sempre registrato. I problemi che giustificano una registrazione al livello ERROR sono buoni candidati per essere segnalati a un server che raccoglie statistiche.
  • WARNING: Si usa quando è successo qualcosa di serio e inaspettato, cioè qualcosa che avrà conseguenze visibili all’utente ma che probabilmente sarà recuperabile senza perdita di dati eseguendo qualche azione esplicita, che va dall’attesa o dal riavvio di un’app fino al riscaricamento di una nuova versione di un’app o al riavvio del dispositivo. Questo livello viene sempre registrato. Problemi che giustificano la registrazione al livello WARNING potrebbero anche essere considerati per la segnalazione a un server di raccolta delle statistiche.
  • INFORMATIVE: Si usa per notare che è successo qualcosa di interessante, cioè quando viene rilevata una situazione che può avere un impatto diffuso, anche se non è necessariamente un errore. Una tale condizione dovrebbe essere registrata solo da un modulo che crede di essere il più autorevole in quel dominio (per evitare la duplicazione della registrazione da parte di componenti non autorevoli). Questo livello viene sempre registrato.
  • DEBUG: Usare per annotare ulteriormente ciò che sta accadendo sul dispositivo che potrebbe essere rilevante per indagare ed eseguire il debug di comportamenti inaspettati. Registra solo ciò che è necessario per raccogliere abbastanza informazioni su ciò che sta accadendo con il tuo componente. Se i vostri log di debug stanno dominando il log, allora dovreste usare il log verboso.

    Questo livello viene registrato anche nelle build di rilascio, e deve essere circondato da un blocco if (LOCAL_LOG) o if LOCAL_LOGD), dove LOCAL_LOG è definito nella tua classe o sottocomponente, in modo che ci sia la possibilità di disabilitare tutti questi log. Pertanto, non ci deve essere alcuna logica attiva in un blocco if (LOCAL_LOG). Anche tutta la costruzione delle stringhe per il log deve essere posta all’interno del blocco if (LOCAL_LOG). Non rifattorizzare la chiamata di log in una chiamata di metodo se questo causerà la costruzione della stringa al di fuori del blocco if (LOCAL_LOG).

    C’è del codice che dice ancora if (localLOGV). Anche questo è considerato accettabile, anche se il nome non è standard.

  • VERBOSE: Da usare per tutto il resto. Questo livello viene registrato solo nelle build di debug e dovrebbe essere circondato da un blocco if (LOCAL_LOGV) (o equivalente) in modo che possa essere compilato di default. Qualsiasi costruzione di stringhe viene rimossa dalle build di rilascio e deve apparire all’interno del blocco if (LOCAL_LOGV).

Note

  • All’interno di un dato modulo, a parte il livello VERBOSE, un errore dovrebbe essere riportato solo una volta se possibile. All’interno di una singola catena di chiamate di funzioni all’interno di un modulo, solo la funzione più interna dovrebbe restituire l’errore, e i chiamanti nello stesso modulo dovrebbero aggiungere dei log solo se ciò aiuta significativamente ad isolare il problema.
  • In una catena di moduli, oltre che al livello VERBOSE, quando un modulo di livello inferiore rileva dati non validi provenienti da un modulo di livello superiore, il modulo di livello inferiore dovrebbe solo registrare questa situazione nel DEBUG log, e solo se la registrazione fornisce informazioni che non sono altrimenti disponibili al chiamante. In particolare, non c’è bisogno di registrare situazioni in cui viene lanciata un’eccezione (l’eccezione dovrebbe contenere tutte le informazioni rilevanti), o in cui l’unica informazione registrata è contenuta in un codice di errore. Questo è particolarmente importante nell’interazione tra il framework e le app, e le condizioni causate da app di terze parti che sono correttamente gestite dal framework non dovrebbero far scattare la registrazione più in alto del livello DEBUG. Le uniche situazioni che dovrebbero far scattare la registrazione al livello INFORMATIVE o superiore è quando un modulo o un’app rileva un errore al proprio livello o proveniente da un livello inferiore.
  • Quando una condizione che normalmente giustificherebbe una certa registrazione è probabile che si verifichi molte volte, può essere una buona idea implementare qualche meccanismo di limitazione della velocità per evitare di far traboccare i log con molte copie duplicate delle stesse informazioni (o molto simili).
  • Le perdite di connettività di rete sono considerate comuni e sono pienamente attese, e non dovrebbero essere registrate gratuitamente. Una perdita di connettività di rete che ha conseguenze all’interno di un’applicazione dovrebbe essere registrata al livello DEBUG o VERBOSE (a seconda che le conseguenze siano abbastanza serie e inaspettate da essere registrate in una build di rilascio).
  • Avere un file system completo su un file system che è accessibile a o per conto di applicazioni di terze parti non dovrebbe essere registrato ad un livello superiore a INFORMATIVE.
  • I dati non validi provenienti da qualsiasi fonte non fidata (incluso qualsiasi file su storage condiviso, o dati provenienti da una connessione di rete) sono considerati attesi e non dovrebbero innescare alcuna registrazione ad un livello superiore a DEBUG quando vengono rilevati come non validi (e anche allora la registrazione dovrebbe essere il più limitata possibile).
  • Quando viene usato su oggetti String, l’operatore + crea implicitamente un’istanza StringBuilder con la dimensione del buffer di default (16 caratteri) e potenzialmente altri oggetti String temporanei. Quindi creare esplicitamente oggetti StringBuilder non è più costoso che affidarsi all’operatore predefinito + (e può essere molto più efficiente). Si tenga presente che il codice che chiama Log.v() viene compilato ed eseguito nelle build di rilascio, inclusa la costruzione delle stringhe, anche se i log non vengono letti.
  • Qualsiasi log destinato ad essere letto da altre persone e ad essere disponibile nelle build di rilascio dovrebbe essere conciso senza essere criptico, e dovrebbe essere comprensibile. Questo include tutti i log fino al livello DEBUG.
  • Quando possibile, mantenere i log su una singola linea. Lunghezze di linea fino a 80 o 100 caratteri sono accettabili. Evitare lunghezze superiori a circa 130 o 160 caratteri (inclusa la lunghezza del tag) se possibile.
  • Se il logging riporta dei successi, non usarlo mai a livelli superiori a VERBOSE.
  • Se stai usando il logging temporaneo per diagnosticare un problema difficile da riprodurre, tienilo al livello DEBUG o VERBOSE e racchiudilo con blocchi if che permettono di disabilitarlo in fase di compilazione.
  • Fate attenzione alle fughe di sicurezza attraverso il log. Evitare di registrare informazioni private. In particolare, evitare di registrare informazioni su contenuti protetti. Questo è particolarmente importante quando si scrive il codice del framework, poiché non è facile sapere in anticipo quali saranno o non saranno informazioni private o contenuti protetti.
  • Non usare mai System.out.println() (o printf() per il codice nativo). System.out e System.err vengono reindirizzati a /dev/null, quindi le vostre dichiarazioni di stampa non hanno effetti visibili. Tuttavia, tutta la costruzione di stringhe che avviene per queste chiamate viene ancora eseguita.
  • La regola d’oro del logging è che i vostri log non possono spingere inutilmente altri log fuori dal buffer, così come gli altri non possono spingere fuori i vostri.

Regole di stile di Javatests

Segui le convenzioni di denominazione dei metodi di test e usa un trattino basso per separare ciò che viene testato dal caso specifico da testare. Questo stile rende più facile vedere quali casi sono stati testati. For example:

testMethod_specificCase1 testMethod_specificCase2void testIsDistinguishable_protanopia() { ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA) assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK)) assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))}

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *