Les styles de code sur cette page sont des règles strictes pour contribuer au code Java de l’Android Open Source Project (AOSP). Les contributions à la plate-forme Android qui n’adhèrent pas à ces règles ne sont généralement pas acceptées. Nous reconnaissons que tout le code existant ne suit pas ces règles, mais nous attendons que tout nouveau code soit conforme. Voir Codage avec respect pour des exemples de terminologie à utiliser et à éviter pour un écosystème plus inclusif.
- Soyez cohérent
- Règles du langage Java
- Ne pas ignorer les exceptions
- Ne pas attraper les exceptions génériques
- Ne pas utiliser les finaliseurs
- Fully qualify imports
- Règles des bibliothèques Java
- Règles de style Java
- Écrire des méthodes courtes
- Définir les champs aux endroits standard
- Limiter la portée des variables
- Order import statements
- Use spaces for indentation
- Follow field naming conventions
- Use standard brace style
- Limit line length
- Utiliser les annotations Java standard
- Treat acronyms as words
- Loguer avec parcimonie
- Notes
- Règles de style de Javatests
Soyez cohérent
L’une des règles les plus simples est d’être cohérent. Si vous éditez du code, prenez quelques minutes pour regarder le code environnant et déterminer son style. Si ce code utilise des espaces autour des clauses if
, vous devriez en faire autant. Si les commentaires du code ont des petites boîtes d’étoiles autour d’eux, faites en sorte que vos commentaires aient aussi des petites boîtes d’étoiles autour d’eux.
L’intérêt d’avoir des règles de style est d’avoir un vocabulaire commun de codage, afin que les lecteurs puissent se concentrer sur ce que vous dites, plutôt que sur la façon dont vous le dites. Nous présentons ici des règles de style globales afin que vous connaissiez le vocabulaire, mais le style local est également important. Si le code que vous ajoutez à un fichier est radicalement différent du code existant qui l’entoure, le lecteur sera déstabilisé à la lecture. Essayez d’éviter cela.
Règles du langage Java
Androïd suit les conventions de codage Java standard avec les règles supplémentaires décrites ci-dessous.
Ne pas ignorer les exceptions
Il peut être tentant d’écrire du code qui ignore une exception, comme par exemple :
void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { } }
Ne faites pas cela. Bien que vous puissiez penser que votre code ne rencontrera jamais cette condition d’erreur ou qu’il n’est pas important de la gérer, ignorer ce type d’exception crée des mines dans votre code pour que quelqu’un d’autre les déclenche un jour. Vous devez traiter chaque exception dans votre code d’une manière fondée sur des principes ; le traitement spécifique varie en fonction du cas.
« Chaque fois que quelqu’un a une clause catch vide, il devrait avoir un sentiment de chair de poule. Il y a certainement des moments où c’est en fait la chose correcte à faire, mais au moins vous devez y penser. En Java, vous ne pouvez pas échapper au sentiment de chair de poule. » – James Gosling
Les alternatives acceptables (par ordre de préférence) sont :
- Lancer l’exception jusqu’à l’appelant de votre méthode.
void setServerPort(String value) throws NumberFormatException { serverPort = Integer.parseInt(value); }
- Lancer une nouvelle exception qui est appropriée à votre niveau d’abstraction.
void setServerPort(String value) throws ConfigurationException { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { throw new ConfigurationException("Port " + value + " is not valid."); } }
- Gérer l’erreur avec élégance et substituer une valeur appropriée dans le bloc
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 } }
- Rattraper l’exception et lancer une nouvelle instance de
RuntimeException
. Ceci est dangereux, donc ne le faites que si vous êtes positif que si cette erreur se produit, la chose appropriée à faire est de se planter./** 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); } }
- En dernier recours, si vous êtes sûr qu’ignorer l’exception est approprié, alors vous pouvez l’ignorer, mais vous devez également commenter pourquoi avec une bonne raison.
/** 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. }}
Ne pas attraper les exceptions génériques
Il peut être tentant d’être paresseux lors de la capture des exceptions et de faire quelque chose comme ceci :
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! }
Ne faites pas cela. Dans presque tous les cas, il est inapproprié de capturer des exceptions génériques Exception
ou Throwable
(de préférence pas Throwable
car elle inclut des exceptions Error
). C’est dangereux car cela signifie que les exceptions auxquelles vous ne vous attendiez pas (y compris les exceptions d’exécution comme ClassCastException
) sont capturées dans la gestion des erreurs au niveau de l’application. Il masque les propriétés de gestion des erreurs de votre code, ce qui signifie que si quelqu’un ajoute un nouveau type d’exception dans le code que vous appelez, le compilateur ne signalera pas que vous devez gérer l’erreur différemment. Dans la plupart des cas, vous ne devriez pas gérer différents types d’exceptions de la même manière.
La rare exception à cette règle est le code de test et le code de haut niveau où vous voulez attraper toutes sortes d’erreurs (pour éviter qu’elles ne s’affichent dans une interface utilisateur, ou pour maintenir l’exécution d’un travail par lots). Dans ces cas, vous pouvez attraper des Exception
génériques (ou Throwable
) et traiter l’erreur de manière appropriée. Réfléchissez bien avant de faire cela, cependant, et mettez des commentaires expliquant pourquoi c’est sûr dans ce contexte.
Alternatives à la capture des exceptions génériques :
- Capturer chaque exception séparément dans le cadre d’un bloc multi-catch, par exemple :
try { ...} catch (ClassNotFoundException | NoSuchMethodException e) { ...}
- Réfacturer votre code pour avoir une gestion des erreurs plus fine, avec plusieurs blocs try. Séparez l’IO de l’analyse syntaxique, et gérez les erreurs séparément dans chaque cas.
- Rethrow l’exception. Bien souvent, vous n’avez pas besoin d’attraper l’exception à ce niveau de toute façon, laissez simplement la méthode la lancer.
Souvenez-vous que les exceptions sont vos amies ! Lorsque le compilateur se plaint que vous n’attrapez pas une exception, ne faites pas la grimace. Souriez ! Le compilateur vient de vous faciliter la tâche pour attraper les problèmes d’exécution dans votre code.
Ne pas utiliser les finaliseurs
Les finaliseurs sont un moyen de faire exécuter un morceau de code lorsqu’un objet est mis à la poubelle. Bien que les finaliseurs puissent être pratiques pour le nettoyage (notamment des ressources externes), il n’y a aucune garantie quant au moment où un finaliseur sera appelé (ou même qu’il sera appelé tout court).
Androïd n’utilise pas de finaliseurs. Dans la plupart des cas, vous pouvez utiliser une bonne gestion des exceptions à la place. 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.*
).
Règles des bibliothèques Java
Il existe des conventions pour l’utilisation des bibliothèques et outils Java d’Android. Dans certains cas, la convention a changé de manière importante et un code plus ancien pourrait utiliser un motif ou une bibliothèque dépréciée. Lorsque vous travaillez avec un tel code, il est correct de continuer le style existant. Cependant, lors de la création de nouveaux composants, n’utilisez jamais de bibliothèques dépréciées.
Règles de style Java
Tout fichier doit comporter une déclaration de copyright en haut, suivie des déclarations de package et d’import (chaque bloc étant séparé par une ligne blanche), et enfin la déclaration de classe ou d’interface. Dans les commentaires Javadoc, décrivez ce que fait la classe ou l’interface.
/* * 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 { ...}
Chaque classe et méthode publique non triviale que vous écrivez doit contenir un commentaire Javadoc avec au moins une phrase décrivant ce que fait la classe ou la méthode. Cette phrase doit commencer par un verbe descriptif à la troisième personne.
Exemples
/** Returns the correctly rounded positive square root of a double value. */static double sqrt(double a) { ...}
ou
/** * Constructs a new String by converting the specified array of * bytes using the platform's default character encoding. */public String(byte bytes) { ...}
Vous n’avez pas besoin d’écrire de Javadoc pour des méthodes get et set triviales telles que setFoo()
si tout ce que votre Javadoc dit est « sets Foo ». Si la méthode fait quelque chose de plus complexe (comme faire respecter une contrainte ou avoir un effet secondaire important), alors vous devez le documenter. S’il n’est pas évident de savoir ce que la propriété « Foo » signifie, vous devez le documenter.
Chaque méthode que vous écrivez, publique ou non, bénéficierait d’un Javadoc. Les méthodes publiques font partie d’une API et nécessitent donc une Javadoc. Android n’impose pas un style spécifique pour l’écriture des commentaires Javadoc, mais vous devriez suivre les instructions de la section Comment écrire des commentaires de doc pour l’outil Javadoc.
Écrire des méthodes courtes
Lorsque cela est possible, gardez les méthodes petites et ciblées. Nous reconnaissons que les longues méthodes sont parfois appropriées, donc aucune limite stricte n’est placée sur la longueur des méthodes. Si une méthode dépasse 40 lignes environ, réfléchissez à la possibilité de la fractionner sans nuire à la structure du programme.
Définir les champs aux endroits standard
Définir les champs soit en haut du fichier, soit immédiatement avant les méthodes qui les utilisent.
Limiter la portée des variables
Maintenir la portée des variables locales au minimum. Cela augmente la lisibilité et la maintenabilité de votre code et réduit la probabilité d’erreur. Déclarez chaque variable dans le bloc le plus interne qui englobe toutes les utilisations de la variable.
Déclarez les variables locales au moment où elles sont utilisées pour la première fois. Presque chaque déclaration de variable locale doit contenir un initialisateur. Si vous n’avez pas encore assez d’informations pour initialiser une variable de manière raisonnable, reportez la déclaration jusqu’à ce que vous le fassiez.
L’exception est constituée par les déclarations try-catch. Si une variable est initialisée avec la valeur de retour d’une méthode qui lève une exception vérifiée, elle doit être initialisée à l’intérieur d’un bloc 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:
- Android imports
- Imports from third parties (
com
junit
net
org
) -
java
andjavax
To exactly match the IDE settings, the imports should be:
- Alphabétique à l’intérieur de chaque groupement, avec les majuscules avant les minuscules (par exemple, Z avant a)
- Séparés par une ligne blanche entre chaque groupement majeur (
android
com
junit
net
org
java
javax
).
À l’origine, il n’y avait pas d’exigence de style sur l’ordre, ce qui signifie que soit les IDE changeaient constamment l’ordre, soit les développeurs d’IDE devaient désactiver les fonctions de gestion automatique des importations et maintenir manuellement les importations. Cette situation était considérée comme mauvaise. Lorsque la question du style Java a été posée, les styles préférés variaient énormément et il a été décidé qu’Android devait simplement « choisir un ordre et être cohérent ». Nous avons donc choisi un style, mis à jour le guide de style et fait en sorte que les EDI s’y conforment. Nous nous attendons à ce que, à mesure que les utilisateurs d’IDE travaillent sur le code, les importations dans tous les paquets correspondent à ce modèle sans effort d’ingénierie supplémentaire.
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:
- Si une ligne de commentaire contient un exemple de commande ou une URL littérale de plus de 100 caractères, cette ligne peut être plus longue que 100 caractères pour faciliter le couper-coller.
- Les lignes d’importation peuvent dépasser la limite car les humains les voient rarement (cela simplifie également l’écriture des outils).
Utiliser les annotations Java standard
Les annotations doivent précéder les autres modificateurs pour le même élément de langage. Les annotations de marqueurs simples (par exemple, @Override
) peuvent être énumérées sur la même ligne que l’élément de langage. S’il y a plusieurs annotations, ou des annotations paramétrées, listez-les une par ligne par ordre alphabétique.
Les pratiques standard d’Android pour les trois annotations prédéfinies en Java sont :
- Utiliser l’annotation
@Deprecated
chaque fois que l’utilisation de l’élément annoté est déconseillée. Si vous utilisez l’annotation@Deprecated
, vous devez également avoir une balise Javadoc@deprecated
et elle doit nommer une implémentation alternative. En outre, n’oubliez pas qu’une méthode@Deprecated
est toujours censée fonctionner. Si vous voyez un ancien code qui a une balise Javadoc@deprecated
, ajoutez l’annotation@Deprecated
. - Utilisez l’annotation
@Override
chaque fois qu’une méthode surcharge la déclaration ou l’implémentation d’une superclasse. Par exemple, si vous utilisez la balise Javadoc@inheritdocs
, et que vous dérivez d’une classe (et non d’une interface), vous devez également annoter que la méthode surcharge la méthode de la classe parente. - N’utilisez l’annotation
@SuppressWarnings
que dans les circonstances où il est impossible d’éliminer un avertissement. 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 aTODO
comment that explains the « impossible to eliminate » condition. This normally identifies an offending class that has an awkward interface. Par exemple :// 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.
et
// TODO: Change this to use a flag instead of a constant.
Si votre TODO
est de la forme « À une date ultérieure, faites quelque chose », assurez-vous d’inclure soit une date précise (« Corriger d’ici novembre 2005 »), soit un événement spécifique (« Supprimer ce code après que tous les mélangeurs de production aient compris le protocole V7. »).
Loguer avec parcimonie
Si la journalisation est nécessaire, elle a un impact négatif sur les performances et perd de son utilité si elle n’est pas maintenue raisonnablement laconique. Les installations de journalisation fournissent cinq niveaux différents de journalisation :
-
ERROR
: À utiliser lorsque quelque chose de fatal s’est produit, c’est-à-dire quelque chose qui aura des conséquences visibles pour l’utilisateur et qui ne sera pas récupérable sans effacer certaines données, désinstaller des apps, effacer les partitions de données ou reflasher tout l’appareil (ou pire). Ce niveau est toujours enregistré. Les problèmes qui justifient une certaine journalisation au niveauERROR
sont de bons candidats pour être signalés à un serveur de collecte de statistiques. -
WARNING
: À utiliser lorsque quelque chose de grave et d’inattendu s’est produit, c’est-à-dire quelque chose qui aura des conséquences visibles pour l’utilisateur mais qui est susceptible d’être récupéré sans perte de données en effectuant une action explicite, allant de l’attente ou du redémarrage d’une app jusqu’au retéléchargement d’une nouvelle version d’une app ou au redémarrage de l’appareil. Ce niveau est toujours consigné. Les problèmes qui justifient une journalisation au niveauWARNING
pourraient également être envisagés pour être signalés à un serveur de collecte de statistiques. -
INFORMATIVE
: Utiliser pour noter que quelque chose d’intéressant s’est produit, c’est-à-dire lorsqu’une situation est détectée qui est susceptible d’avoir un impact généralisé, bien qu’elle ne soit pas nécessairement une erreur. Une telle situation ne devrait être consignée que par un module qui estime être le plus compétent dans ce domaine (pour éviter la consignation en double par des composants non compétents). Ce niveau est toujours journalisé. -
DEBUG
: Utiliser pour noter davantage ce qui se passe sur l’appareil et qui pourrait être pertinent pour enquêter et déboguer des comportements inattendus. N’enregistrez que ce qui est nécessaire pour recueillir suffisamment d’informations sur ce qui se passe avec votre composant. Si vos journaux de débogage dominent le journal, alors vous devriez utiliser la journalisation verbeuse.Ce niveau est journalisé même sur les builds de version, et doit être entouré d’un bloc
if (LOCAL_LOG)
ouif LOCAL_LOGD)
, oùLOCAL_LOG
est défini dans votre classe ou sous-composant, afin qu’il y ait une possibilité de désactiver toute cette journalisation. Par conséquent, il ne doit y avoir aucune logique active dans un blocif (LOCAL_LOG)
. Toute la construction de chaînes pour le journal doit également être placée à l’intérieur du blocif (LOCAL_LOG)
. Ne refactorez pas l’appel de journalisation en un appel de méthode si cela doit entraîner la construction de la chaîne de caractères en dehors du blocif (LOCAL_LOG)
.Il y a encore du code qui dit
if (localLOGV)
. Cela est considéré comme acceptable également, bien que le nom soit non standard. -
VERBOSE
: À utiliser pour tout le reste. Ce niveau est uniquement enregistré sur les builds de débogage et doit être entouré d’un blocif (LOCAL_LOGV)
(ou équivalent) afin qu’il puisse être compilé par défaut. Toute construction de chaîne est supprimée des builds de version et doit apparaître à l’intérieur du blocif (LOCAL_LOGV)
.
Notes
- Dans un module donné, autre qu’au niveau
VERBOSE
, une erreur ne doit être signalée qu’une seule fois si possible. Dans une seule chaîne d’appels de fonctions au sein d’un module, seule la fonction la plus interne devrait renvoyer l’erreur, et les appelants du même module ne devraient ajouter une certaine journalisation que si cela aide significativement à isoler le problème. - Dans une chaîne de modules, autre qu’au niveau
VERBOSE
, lorsqu’un module de niveau inférieur détecte des données invalides provenant d’un module de niveau supérieur, le module de niveau inférieur ne devrait consigner cette situation que dans le journalDEBUG
, et seulement si la consignation fournit des informations qui ne sont pas autrement disponibles pour l’appelant. Plus précisément, il n’est pas nécessaire de consigner les situations où une exception est levée (l’exception doit contenir toutes les informations pertinentes), ou lorsque la seule information consignée est contenue dans un code d’erreur. Ceci est particulièrement important dans l’interaction entre le framework et les apps, et les conditions causées par des apps tierces qui sont correctement gérées par le framework ne devraient pas déclencher de journalisation supérieure au niveauDEBUG
. Les seules situations qui devraient déclencher la journalisation au niveauINFORMATIVE
ou plus haut sont lorsqu’un module ou une app détecte une erreur à son propre niveau ou provenant d’un niveau inférieur. - Lorsqu’une condition qui justifierait normalement une certaine journalisation est susceptible de se produire de nombreuses fois, il peut être judicieux d’implémenter un mécanisme de limitation du débit pour éviter de submerger les journaux avec de nombreuses copies en double de la même information (ou d’une information très similaire).
- Les pertes de connectivité réseau sont considérées comme courantes et sont tout à fait attendues, et ne devraient pas être consignées gratuitement. Une perte de connectivité réseau qui a des conséquences au sein d’une app devrait être consignée au niveau
DEBUG
ouVERBOSE
(selon que les conséquences sont suffisamment sérieuses et inattendues pour être consignées dans une release build). - Avoir un système de fichiers complet sur un système de fichiers accessible à ou pour le compte d’apps tierces ne devrait pas être consigné à un niveau supérieur à INFORMATIF.
- Les données invalides provenant de toute source non fiable (y compris tout fichier sur un stockage partagé, ou les données provenant d’une connexion réseau) sont considérées comme attendues et ne devraient pas déclencher de journalisation à un niveau supérieur à
DEBUG
lorsqu’elles sont détectées comme étant invalides (et même dans ce cas, la journalisation devrait être aussi limitée que possible). - Lorsqu’il est utilisé sur des objets
String
, l’opérateur+
crée implicitement une instanceStringBuilder
avec la taille de tampon par défaut (16 caractères) et potentiellement d’autres objetsString
temporaires. Ainsi, créer explicitement des objetsStringBuilder
n’est pas plus coûteux que de s’appuyer sur l’opérateur par défaut+
(et peut être beaucoup plus efficace). Gardez à l’esprit que le code qui appelleLog.v()
est compilé et exécuté sur les builds de la version, y compris la construction des chaînes, même si les logs ne sont pas lus. - Tout logging destiné à être lu par d’autres personnes et à être disponible dans les release builds doit être laconique sans être cryptique, et doit être compréhensible. Cela inclut toute la journalisation jusqu’au niveau
DEBUG
. - Dans la mesure du possible, gardez la journalisation sur une seule ligne. Les longueurs de ligne jusqu’à 80 ou 100 caractères sont acceptables. Évitez si possible les longueurs supérieures à environ 130 ou 160 caractères (y compris la longueur de la balise).
- Si la journalisation rapporte les succès, ne l’utilisez jamais à des niveaux supérieurs à
VERBOSE
. - Si vous utilisez la journalisation temporaire pour diagnostiquer un problème difficile à reproduire, maintenez-la au niveau
DEBUG
ouVERBOSE
et enfermez-la dans des blocs if qui permettent de la désactiver au moment de la compilation. - Faites attention aux fuites de sécurité à travers le journal. Évitez de journaliser des informations privées. En particulier, évitez de consigner des informations sur le contenu protégé. Ceci est particulièrement important lors de l’écriture du code du framework car il n’est pas facile de savoir à l’avance ce qui sera et ne sera pas une information privée ou un contenu protégé.
- Ne jamais utiliser
System.out.println()
(ouprintf()
pour le code natif).System.out
etSystem.err
sont redirigés vers/dev/null
, de sorte que vos instructions print n’ont aucun effet visible. Cependant, toute la construction de chaîne qui se produit pour ces appels est toujours exécutée. - La règle d’or de la journalisation est que vos journaux ne doivent pas pousser inutilement les autres journaux hors du tampon, tout comme les autres ne doivent pas pousser les vôtres.
Règles de style de Javatests
Suivez les conventions de nommage des méthodes de test et utilisez un trait de soulignement pour séparer ce qui est testé du cas spécifique testé. Ce style permet de voir plus facilement quels cas sont testés. 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))}